甲骨文离开一对多

时间:2018-09-27 13:26:16

标签: oracle

我有两个表(例如最小化)

表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   

请帮我解释一下这里出了什么问题。

3 个答案:

答案 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;

enter image description here

Demo

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