Oracle se unió a la izquierda y donde las cláusulas errores

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    

Esto funciona como se esperaba. La cuestión es que siempre quiero que se muestren todas las filas de ATABLE1 y también aplique algunas restricciones.

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 qué no se muestran todas las columnas de ATABLE1 incluso con la unión izquierda? ¿Cómo puedo hacer que aparezcan?

Muchas gracias por adelantado.

Rafa de Castro
fuente
+1, especialmente por el esfuerzo que ha puesto en configurar los objetos de prueba
Jack dice que intente topanswers.xyz
"¿Por qué no se muestran todas las columnas de ATABLE1 incluso con la unión izquierda?" - ¿Querías decir 'todas las filas'?
Jack dice que intente topanswers.xyz
@JackDouglas sí, eso tendría más sentido.
Aaron

Respuestas:

7

Cuando agrega filtros WHERE a la tabla opcional / externa, cambia la consulta a INNER JOIN. Debe agregar la condición a la unión, o tabla derivada, o 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
fuente
3

¿Por qué no se muestran todas las columnas de ATABLE1 incluso con la unión izquierda? ¿Cómo puedo hacer que aparezcan?

Esto se debe a que le está diciendo a su consulta que solo devuelva ATABLE.column1. Si acepta consultas de gbn o Jack, solo indique ATABLE1. * (O nombre específicamente cada una de ellas) en su cláusula 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
fuente
1
Interesante, espero que el OP no esté confundido sobre cómo enumerar todas las columnas. Por otro lado, eso es lo que pidieron. +1.
Leigh Riffel
2

Una alternativa para agregar la condición a la unión es probar nullen el filtro:

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;

Prefiero esta variante, pero puede considerarla menos legible:

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 única razón para hacerlo es si por alguna razón no puede poner la condición en el filtro (que a veces es el caso en una consulta más compleja)

Jack dice que intente topanswers.xyz
fuente