关于Left Join SQL的困惑

时间:2012-11-26 18:08:27

标签: sql database left-join

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

表名:products

加入条件列:prdname

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

Objecttive

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


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

我怀疑他们两个都差不多,为什么秒不正确呢?

任何人都可以帮助我吗?

此外,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') 

1 个答案:

答案 0 :(得分:3)

通过在“外部”表的列上添加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;

为了使事情更清楚,这是一个简化的例子。

假设有以下表格:

id | firstname | lastname  
---+-----------+-----------
1  | Arthur    | Dent      
4  | Mary      | Moviestar 
2  | Zaphod    | Beeblebrox
3  | Tricia    | McMillian 

车辆

id | person_id | vehicle_name
---+-----------+-------------
1  | 1         | Arthur's car
2  | 2         | Zaphod's car

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

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

返回以下内容:

id | firstname | vehicle_name
---+-----------+-------------
1  | Arthur    | Arthur's car
2  | Zaphod    | Zaphod's car
3  | Tricia    | (null)      
4  | Mary      | (null)      

现在考虑添加

时会发生什么
and v.vehicle_name = 'Arthur''s car' 

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


现在回答你真正的问题:

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

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

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