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
Isso funciona conforme o esperado. O problema é que eu sempre quero que todas as linhas de ATABLE1 sejam mostradas e também aplico algumas restrições.
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
Por que nem todas as colunas de ATABLE1 são exibidas, mesmo com a junção esquerda? Como posso fazê-los aparecer?
Muito obrigado antecipadamente.
Respostas:
Quando você adiciona filtros WHERE à tabela opcional / externa, altera a consulta para uma INNER JOIN. Você precisa adicionar a condição à junção, tabela derivada ou CTE.
fonte
Isso ocorre porque você está dizendo à sua consulta para trazer apenas de volta ATABLE.column1. Se você atender às consultas do gbn ou de Jack, basta indicar ATABLE1. * (Ou nomeie especificamente cada uma delas) na sua cláusula SELECT:
fonte
Uma alternativa para adicionar a condição à junção é testar
null
no filtro:Prefiro essa variante, mas você pode considerá-la menos legível:
O único motivo para fazer isso é se, por algum motivo, você não conseguir colocar a condição no filtro (o que às vezes ocorre em uma consulta mais complexa)
fonte