Oracle的左连接和where子句错误


10
CREATE TABLE "ATABLE1"
  (
    "COLUMN1" VARCHAR2(20 BYTE),
    "COLUMN2" VARCHAR2(20 BYTE)
  );

CREATE TABLE "ATABLE2"
  (
    "COLUMN1" VARCHAR2(20 BYTE),
    "COLUMN2" VARCHAR2(20 BYTE)
  );

Insert into ATABLE1 (COLUMN1,COLUMN2) values ('A','1');
Insert into ATABLE1 (COLUMN1,COLUMN2) values ('B','2');

Insert into ATABLE2 (COLUMN1,COLUMN2) values ('A',null);
Insert into ATABLE2 (COLUMN1,COLUMN2) values ('A','1');
Insert into ATABLE2 (COLUMN1,COLUMN2) values ('A','2');

select ATABLE1.column1, count(ATABLE2.column1) 
    from ATABLE1 Left OUTER JOIN ATABLE2 on ATABLE1.column1 = atable2.column1
    GROUP BY ATABLE1.column1;

Result

COLUMN1              COUNT(ATABLE2.COLUMN1) 
-------------------- ---------------------- 
A                    3                      
B                    0    

这按预期工作。事实是,我总是希望显示ATABLE1中的所有行,并且还施加一些限制。

select ATABLE1.column1, count(ATABLE2.column1) 
    from ATABLE1 Left OUTER JOIN ATABLE2 on ATABLE1.column1 = atable2.column1
    where atable2.column2 = '1'
    GROUP BY ATABLE1.column1;


COLUMN1              COUNT(ATABLE2.COLUMN1) 
-------------------- ---------------------- 
A                    1                      

为什么即使左联接也不会显示ATABLE1的所有列?如何使它们出现?

非常感谢。


+1,尤其是在设置测试对象上所付出的努力
杰克说,请尝试topanswers.xyz 2012年

“为什么即使左连接也不会显示ATABLE1的所有列?” -您是要说“所有行”吗?
杰克说试试topanswers.xyz 2012年

@JackDouglas是的,那会更有意义。
亚伦

Answers:


7

当您将WHERE过滤器添加到可选表/外部表时,则可以将查询更改为INNER JOIN。您需要将条件添加到联接或派生表或CTE中。

select ATABLE1.column1, count(ATABLE2.column1) 
    from ATABLE1 Left OUTER JOIN ATABLE2
         on ATABLE1.column1 = atable2.column1 AND atable2.column2 = '1'
    GROUP BY ATABLE1.column1;

3

为什么即使左联接也不会显示ATABLE1的所有列?如何使它们出现?

那是因为您要告诉查询仅带回ATABLE.column1。如果您使用gbn或Jack的查询,只需在SELECT子句中指出ATABLE1。*(或分别命名它们):

select ATABLE1.*, count(ATABLE2.column1) 
from ATABLE1 Left OUTER JOIN ATABLE2
     on ATABLE1.column1 = atable2.column1 AND atable2.column2 = '1'
GROUP BY ATABLE1.column1;

1
有趣的是,我希望OP不要对如何列出所有列感到困惑。另一方面,这就是他们的要求。+1。
Leigh Riffel 2012年

2

将条件添加联接的另一种方法是null在过滤器中进行测试:

select ATABLE1.column1, count(ATABLE2.column1) 
    from ATABLE1 Left OUTER JOIN ATABLE2 on ATABLE1.column1 = atable2.column1
    where atable2.column2 is null or atable2.column2 = '1'
    GROUP BY ATABLE1.column1;

我更喜欢这种变体,但您可能会认为它的可读性较差:

select ATABLE1.column1, count(ATABLE2.column1) 
    from ATABLE1 Left OUTER JOIN ATABLE2 on ATABLE1.column1 = atable2.column1
    where decode(atable2.column2,'1',1,null,1,0)=1
    GROUP BY ATABLE1.column1;

这样做的唯一原因是,如果由于某种原因您无法将条件放入过滤器中(有时在更复杂的查询中就是这种情况)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.