我必须写一个LEFT JOIN
查询来查找一个表中存在的记录并存在于其他表中(左连接的标准用法)。这一个中只有一个表用于连接。
表名:products
加入条件列:prdname
两个where子句条件:subdivision='abc', subdivision='xyz'
Objecttive
有了这两个where子句,我将得到两个包含两组prdname的结果,我必须找到prdname,它在一个中退出但在另一个中不存在。
当我编写标准LEFT JOIN
时(下面的情况2),它没有给出任何不正确的结果,所以我写了一个子查询来检查结果。这是8条记录所以我决定在这里将查询修改为case1,并且它有效。
我怀疑他们两个都差不多,为什么秒不正确呢?
任何人都可以帮助我吗?
此外,abc
和xyz
是随机值,因此对此非常感兴趣。
正在运作的案例:
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')
答案 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
)