Der linke Join von Oracle und wo Klauseln Fehler

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    

Dies funktioniert wie erwartet. Die Sache ist, dass ich immer möchte, dass alle Zeilen von ATABLE1 angezeigt werden und auch einige Einschränkungen gelten.

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                      

Warum werden nicht alle Spalten von ATABLE1 auch bei Linksverknüpfung angezeigt? Wie kann ich sie erscheinen lassen?

Vielen Dank im Voraus.

Rafa de Castro
quelle
+1, besonders für den Aufwand, den Sie in die Einrichtung der Testobjekte gesteckt haben
Jack sagt, versuchen Sie es mit topanswers.xyz am
"Warum werden nicht alle Spalten von ATABLE1 auch bei Linksverknüpfung angezeigt?" - Wollten Sie "alle Zeilen" sagen?
Jack sagt, versuchen Sie es mit topanswers.xyz am
@ JackDouglas ja, das wäre sinnvoller.
Aaron

Antworten:

7

Wenn Sie der optionalen / äußeren Tabelle WHERE-Filter hinzufügen, ändern Sie die Abfrage in eine INNER JOIN. Sie müssen die Bedingung zum Join, zur abgeleiteten Tabelle oder zum CTE hinzufügen.

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
quelle
3

Warum werden nicht alle Spalten von ATABLE1 auch bei Linksverknüpfung angezeigt? Wie kann ich sie erscheinen lassen?

Das liegt daran, dass Sie Ihrer Abfrage mitteilen, dass nur ATABLE.column1 zurückgebracht werden soll. Wenn Sie Anfragen von gbn oder Jack annehmen, geben Sie in Ihrer SELECT-Klausel einfach ATABLE1. * An (oder benennen Sie jeden von ihnen speziell):

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
quelle
1
Interessanterweise hoffe ich, dass das OP nicht verwirrt ist, wie alle Spalten aufgelistet werden sollen. Auf der anderen Seite haben sie darum gebeten. +1.
Leigh Riffel
2

Eine Alternative zum Hinzufügen der Bedingung zum Join besteht darin, nullim Filter zu testen :

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;

Ich bevorzuge diese Variante, aber Sie können sie als weniger lesbar betrachten:

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;

Der einzige Grund dafür ist, dass Sie die Bedingung aus irgendeinem Grund nicht in den Filter einfügen können (was manchmal bei einer komplexeren Abfrage der Fall ist).

Jack sagt, versuchen Sie es mit topanswers.xyz
quelle