Oracle оставил соединение и где ошибки пунктов

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
«Почему не все столбцы из ATABLE1 отображаются даже при левом соединении?» - Вы хотели сказать «все ряды»?
Джек говорит, попробуйте topanswers.xyz
@JackDouglas да, это будет иметь больше смысла.
Аарон

Ответы:

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, просто укажите ATABLE1. * (Или конкретно назовите каждый из них) в предложении SELECT:

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
Интересно, что я уверен, что ОП не смущен тем, как перечислить все столбцы. С другой стороны, это то, что они просили. +1.
Ли Риффель
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;

Единственная причина сделать это, если по какой-то причине вы не можете поместить условие в фильтр (что иногда имеет место в более сложном запросе)

Джек говорит, попробуйте topanswers.xyz
источник