ANSI OUTER JOINS: parecido no es igual (II)

Ya vimos que las ‘ANSI OUTER JOINS’ tienen sus particularidades. A raíz de esa entrada recibí un confuso ‘mail’ que intentaba rebatir el planteamiento basándose en un ‘contraejemplo’. El remitente no se daba cuenta de que estaba cometiendo un error básico que invalidaba de raíz toda la argumentación.

Vamos a ver como un pequeño cambio en la condición de un ‘JOIN’ puede suponer también grandes diferencias.

Partimos de dos simples tablas de pruebas:

 BTEQ -- Enter your DBC/SQL request or BTEQ command:
SELECT * FROM  MY_DB.PRUEBA02 ORDER BY ID_N;


 *** Query completed. 2 rows found. 2 columns returned.
 *** Total elapsed time was 1 second.

       ID_N  C_TXT
-----------  -------------------------
          1  UNO
          2  DOS

 BTEQ -- Enter your DBC/SQL request or BTEQ command:
SELECT * FROM  MY_DB.PRUEBA04 ORDER BY ID_N,ID_N_SEC;


 *** Query completed. 3 rows found. 2 columns returned.
 *** Total elapsed time was 1 second.

       ID_N     ID_N_SEC
-----------  -----------
          1       (null)
          1            1
          1            2

Si efectuamos una query con una ‘OUTER JOIN’ similar a la de la entrada citada:

 BTEQ -- Enter your DBC/SQL request or BTEQ command:
SELECT *
  FROM MY_DB.PRUEBA02 a
  LEFT OUTER JOIN MY_DB.PRUEBA04 b
               ON a.ID_N=b.ID_N AND a.ID_N=1;


 *** Query completed. 4 rows found. 4 columns returned.
 *** Total elapsed time was 1 second.

       ID_N  C_TXT                             ID_N     ID_N_SEC
-----------  -------------------------  -----------  -----------
          2  DOS                             (null)       (null)
          1  UNO                                  1       (null)
          1  UNO                                  1            1
          1  UNO                                  1            2

Obtenemos cuatro filas: las tres filas como resultado del cruce de una única fila de PRUEBA02 (a) con las tres de PRUEBA04 (b) que corresponden a ID_N=1 y la fila producto del ‘OUTER JOIN’ en que la fila restante de PRUEBA02 (a) no obtiene correspondientes en PRUEBA04 (b), pero que aparece como consecuencia del ‘OUTER JOIN’ con todas las columnas de PRUEBA04 (b) a nulos ya que la condición ‘a.ID_N=1’ no se cumple.

Pero vamos a ver que ocurre con un simple cambio en la condición del ‘JOIN’, simplemente variando la condición desde una columna de la tabla ‘OUTER’ (a.ID_N=1) a una columna de la tabla ‘INNER’ (b.ID_N_SEC=1):

 BTEQ -- Enter your DBC/SQL request or BTEQ command:
SELECT *
  FROM MY_DB.PRUEBA02 a
  LEFT OUTER JOIN MY_DB.PRUEBA04 b
               ON a.ID_N=b.ID_N AND b.ID_N_SEC=1
;


 *** Query completed. 2 rows found. 4 columns returned.
 *** Total elapsed time was 1 second.

       ID_N  C_TXT                             ID_N     ID_N_SEC
-----------  -------------------------  -----------  -----------
          2  DOS                             (null)       (null)
          1  UNO                                  1            1

En efecto: cuando la condición afecta a las columnas de la tabla ‘INNER’ las filas que no la cumplen sí son excluidas del ‘result set’. Este resultado es equivalente a:

 BTEQ -- Enter your DBC/SQL request or BTEQ command:
SELECT *
  FROM MY_DB.PRUEBA02 a
  LEFT OUTER JOIN (SELECT * FROM MY_DB.PRUEBA04 WHERE ID_N_SEC=1) b
               ON a.ID_N=b.ID_N
;


 *** Query completed. 2 rows found. 4 columns returned.
 *** Total elapsed time was 1 second.

       ID_N  C_TXT                             ID_N     ID_N_SEC
-----------  -------------------------  -----------  -----------
          2  DOS                             (null)       (null)
          1  UNO                                  1            1

La fila correspondiente a ID_N=2 sigue apareciendo como antes, con todas las columnas de la tabla PRUEBA04 (b) a nulos. Esto es por la propia naturaleza del ‘OUTER JOIN’: la condición ‘ON a.ID_N=b.ID_N’ implica la tabla ‘OUTER’ y la tabla ‘INNER’, por lo que todas las filas de la tabla ‘OUTER’ deben aparecer.

Otra vez: parecido no es igual.

Son cosas básicas de SQL que muchos ‘expertos’ parecen no conocer…

Saludos.

Carlos.

Anuncios

3 Responses to ANSI OUTER JOINS: parecido no es igual (II)

  1. Luisa dice:

    Hola carlos, queria hacerte una pregunta como funcionaria esta sentencia en teradata 13

    SELECT (CASE
    WHEN TO_CHAR (LAST_DAY (SYSDATE), ‘yyyymmdd’) = TO_CHAR (SYSDATE, ‘yyyymmdd’)
    THEN 1
    ELSE 0
    END
    ) exec_categories
    FROM DUAL

    Ya que last_day es una funcion de oracle

  2. CarlosAL dice:

    Luisita:

    Para saber si un día es el último del mes en Teradata, basta con hacer algo como:

    SELECT 
           CASE 
              WHEN EXTRACT(MONTH FROM DATE)=EXTRACT(MONTH FROM DATE+1)
                 THEN 0
              ELSE 1
           END exec_categories;
    
    

    HTH.

    ¡Recuerdos a Dayton 😉 !

    Saludos.

    Carlos.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: