Oracle 甲骨文左键一对多连接

Oracle 甲骨文左键一对多连接,oracle,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 customerI

我有两张桌子(例如有点小)

表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   

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

不存在
可能是您需要的:

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>
减去
设置运算符(性能比
差不存在
):


不存在
可能是您需要的:

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>
减去
设置运算符(性能比
差不存在
):


您的查询很好,只需将
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还是让我感到害怕。

您的查询很好,只需将
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;
  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

NULL
签入
ON
子句的问题在于,它将导致每个客户记录保留在结果集中,即使该记录与实际订单不匹配。请注意,您的问题有点与我们通常看到的相反,即将逻辑放在
WHERE
子句中,而该子句实际上属于
ON
子句


SQL Server中的演示,因为直到今天Oracle还是让我害怕。

是的,对不起。我还以为是同一个查询接受空检查中的o而不是c。是的,对不起。我认为在空检查中,对o而不是c接受相同的查询。两个查询都在工作。喜欢负数。更糟糕的是,它对性能更差。如果您的表不大,负号就可以正常工作;您不会注意到差异。一个表有1.600.000条记录,另一个甚至更多。这太糟糕了。好吧,尽管如此,如果你尝试一下,也不会花费太多。我接受了另一个问题作为答案,因为我正在寻找一个左连接解决方案。但你的解决方案也很好。因此+1两个查询都在工作。喜欢负数。更糟糕的是,它对性能更差。如果您的表不大,负号就可以正常工作;您不会注意到差异。一个表有1.600.000条记录,另一个甚至更多。这太糟糕了。好吧,尽管如此,如果你尝试一下,也不会花费太多。我接受了另一个问题作为答案,因为我正在寻找一个左连接解决方案。但你的解决方案也很好。So+1
  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