【问题标题】:Confusion regarding Left Join SQL关于左连接 SQL 的困惑
【发布时间】:2012-11-26 18:08:26
【问题描述】:

我必须编写一个LEFT JOIN 查询来查找确实存在于一个表中并存在于另一个表中的记录(左连接的标准用法)。此表中只有一个表用于连接。

表名:products

加入条件栏:prdname

两个where子句条件:subdivision='abc', subdivision='xyz'

客观

通过这两个 where 子句,我将得到两个包含两组 prdname 的结果,我必须找到在一个中存在但在另一个中不存在的 prdname。


当我编写标准LEFT JOIN(下面的案例2)时,它没有给出任何不正确的结果,所以我编写了一个子查询来检查结果。它是 8 条记录,所以我决定在这里将查询修改为 case1,它起作用了。

我怀疑它们两者几乎相同,那么为什么 second 不正确?

谁能帮帮我?

另外,abcxyz 是随机值,所以请多注意它们。

工作的案例:

SELECT a.prdname
FROM   products a
       LEFT OUTER JOIN (SELECT prdname
                        FROM   products
                        WHERE  subdivision = 'xyz') b
                    ON a.prdname = b.prdname
WHERE  a.subdivision = 'abc'
       AND b.prdname IS NULL 

不工作的情况

SELECT DISTINCT( a.prdname )
FROM   products a
       LEFT OUTER JOIN products b
                    ON a.prdname = b.prdname
WHERE  a.subdivision = 'abc'
       AND b.subdivision = 'xyz'
       AND b.prdname IS NULL 

要测试的子查询查询

SELECT DISTINCT( prdname )
FROM   products
WHERE  subdivision = 'abc'
       AND prdname NOT IN (SELECT DISTINCT prdname
                           FROM   products
                           WHERE  subdivision = 'xyz') 

【问题讨论】:

  • “查找确实存在于一个表中并存在于另一个表中的记录” - 这不是 LEFT JOIN 的标准用法。错字,或对连接的错误理解?
  • 错字我猜应该不是。对吗?
  • @Batman 你在想INNER JOIN。请向我们展示一个样本数据集以及所需的结果。
  • 你必须告诉我们你想要得到什么。
  • @njk 格式不错。谢谢你。

标签: sql database left-join


【解决方案1】:

通过在“外部”表的列上添加WHERE 条件,您实际上是将外部联接转换为内部联接,因为那些不满足联接条件的行将在这些列中具有NULL 值。与NULL 的比较会从结果中删除这些行。

您需要将该条件移到 JOIN 子句中:

SELECT a.prdname
FROM   products a
  LEFT JOIN products b
         ON a.prdname = b.prdname
        AND b.subdivision = 'xyz'
WHERE  a.subdivision = 'abc'
   AND b.prdname IS NULL;

为了让事情更清楚一点,这里有一个简化的例子。

假设以下表格:

编号 |名字 |姓 ---+-----------+------------ 1 |亚瑟 |凹痕 4 |玛丽 |影星 2 |赞福德 |比伯布罗克斯 3 |翠西娅 |麦克米利安

车辆

编号 |人名 |车辆名称 ---+-----------+------------- 1 | 1 |亚瑟的车 2 | 2 |赞福德的车

现在获取所有人及其车辆:

select p.id,
       p.firstname, 
       v.vehicle_name
from person p 
   left outer join vehicle v on p.id = v.person_id;

这将返回以下内容:

编号 |名字 |车辆名称 ---+-----------+------------- 1 |亚瑟 |亚瑟的车 2 |赞福德 |赞福德的车 3 |翠西娅 | (空值) 4 |玛丽 | (空值)

现在想想当你添加时会发生什么

and v.vehicle_name = 'Arthur''s car' 

到查询。 vehicle_car 为 null 的两行将不满足该条件,因此从结果中删除。


现在是你真正的问题:

要查找细分“xyz”中不存在的细分“abc”的产品,您可以使用 except 运算符:

select prdname
from products
where subdivision = 'abc'
except
select prdname
from products
where subdivision = 'xyz';

(对于 Oracle,您必须将 except 替换为 minus

【讨论】:

  • 你能详细解释一下或者给这个案例的链接吗,这是我第一次遇到这样的案例
  • @Batman 这是非常标准的 SQL。您必须更具体地说明您需要详细说明的内容。
  • @Batman:这不是一个特殊的“案例”。如果将 NULL 与某些结果进行比较,则结果未定义,因此这些行不是结果的一部分。
  • @a_horse_with_no_name@njk 我无法理解的是您在谈论哪个外部表? .是“先加入还是先在哪里执行”的问题?
  • @Batman:看我的编辑。我添加了一个例子。 “外”表是“左连接”部分中提到的表。
猜你喜欢
  • 2020-12-29
  • 2015-05-27
  • 1970-01-01
  • 2015-10-16
  • 2019-05-17
  • 2020-03-06
  • 2016-03-16
  • 2013-07-27
  • 1970-01-01
相关资源
最近更新 更多