我有两个表(例如最小化)
表1:客户
Id customerName
1 A
2 B
3 C
4 D
表2:订购
Id customerId productName
1 2 ABC
2 2 DEF
3 4 ABC
4 5 FGH
我希望看到所有没有订单的客户。像这样:
customerId
1
3
所以我尝试了
SELECT c.id as customerId
FROM customer_table c
LEFT JOIN order_table o
ON c.id = o.customerId
AND c.customerid IS NULL
但是我得到的结果是:
customerId
1
2
2
3
4
请帮我解释一下这里出了什么问题。
答案 0 :(得分:1)
NOT EXISTS
可能是您需要的:
SQL> with customer (id, name) as
2 (select 1, 'a' from dual union all
3 select 2, 'b' from dual union all
4 select 3, 'c' from dual union all
5 select 4, 'd' from dual
6 ),
7 torder (id, customerid, productname) as
8 (select 1, 2, 'abc' from dual union all
9 select 2, 2, 'def' from dual union all
10 select 3, 4, 'abc' from dual union all
11 select 4, 5, 'fgh' from dual
12 )
13 select c.id
14 from customer c
15 where not exists (select null
16 from torder t
17 where t.customerid = c.id);
ID
----------
3
1
SQL>
或MINUS
集运算符(性能比NOT EXISTS
差):
select c.id from customer c
minus
select t.customerid from torder t;
答案 1 :(得分:1)
您的查询很好,您只需将NULL
检查移到WHERE
子句:
SELECT c.id as customerId
FROM customer_table c
LEFT JOIN order_table o
ON c.id = o.customerId
WHERE o.customerid IS NULL;
将NULL
放在ON
子句中的问题在于,即使该记录与实际订单都不匹配,它也会导致每个客户记录都保留在结果集中。请注意,您的问题与我们通常看到的相反,这是将逻辑放入实际上属于WHERE
子句的ON
子句中。
SQL Server中的演示,因为到目前为止,Oracle吓到了我。
答案 2 :(得分:0)
with tcustomer (id, name) as
(select 1, 'a' from dual union all
select 2, 'b' from dual union all
select 3, 'c' from dual union all
select 4, 'd' from dual
),
torder (id, customerid, productname) as
(select 1, 2, 'abc' from dual union all
select 2, 2, 'def' from dual union all
select 3, 4, 'abc' from dual union all
select 4, 5, 'fgh' from dual
)
select c.id
from tcustomer c
where null not in (select null
from torder t
where t.customerid = c.id);
Output:
ID
1
3