Erreurs de jointure gauche et de clause Where d'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    

Cela fonctionne comme prévu. Le fait est que je veux toujours que toutes les lignes de ATABLE1 soient affichées et que j'applique également certaines restrictions.

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                      

Pourquoi toutes les colonnes d'ATABLE1 ne sont-elles pas affichées même avec la jointure gauche? Comment puis-je les faire apparaître?

Merci beaucoup d'avance.

Rafa de Castro
la source
+1, en particulier pour l'effort que vous avez mis dans la configuration des objets de test
Jack dit d'essayer topanswers.xyz
"Pourquoi toutes les colonnes d'ATABLE1 ne sont-elles pas affichées même avec la jointure gauche?" - vouliez-vous dire «toutes les lignes»?
Jack dit d'essayer topanswers.xyz le
@JackDouglas oui, cela aurait plus de sens.
Aaron

Réponses:

7

Lorsque vous ajoutez des filtres WHERE à la table facultative / externe, vous modifiez la requête en une INNER JOIN. Vous devez ajouter la condition dans la jointure, la table dérivée ou le 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;
gbn
la source
3

Pourquoi toutes les colonnes d'ATABLE1 ne sont-elles pas affichées même avec la jointure gauche? Comment puis-je les faire apparaître?

C'est parce que vous dites à votre requête de ne ramener que ATABLE.column1. Si vous prenez gbn ou les requêtes de Jack, indiquez simplement ATABLE1. * (Ou nommez spécifiquement chacun d'eux) dans votre clause 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;
Aaron
la source
1
Intéressant, j'espère que l'OP n'est pas confus quant à la façon de lister toutes les colonnes. D'un autre côté, c'est ce qu'ils ont demandé. +1.
Leigh Riffel
2

Une alternative à l' ajout de la condition à la jointure consiste à tester nulldans le filtre:

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;

Je préfère cette variante mais vous pouvez la considérer comme moins lisible:

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;

La seule raison pour cela est que, pour une raison quelconque, vous ne pouvez pas mettre la condition dans le filtre (ce qui est parfois le cas dans une requête plus complexe)

Jack dit d'essayer topanswers.xyz
la source