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.


+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;

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;

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)

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.