¿Cuántas tablas ves aquí?

A veces, hasta el SQL más sencillo puede despistar a un observador poco avispado (“basado en hechos reales“).

 BTEQ -- Enter your SQL request or BTEQ command:
CREATE MULTISET TABLE CARLOS.PRUEBA01,
     NO FALLBACK ,
     NO BEFORE JOURNAL,
     NO AFTER JOURNAL,
     CHECKSUM = DEFAULT,
     DEFAULT MERGEBLOCKRATIO
     (
        ID_N  INTEGER     NOT NULL,
        C_TXT VARCHAR(15) NOT NULL
     )
     PRIMARY INDEX ( ID_N )
;


 *** Table has been created.
 *** Total elapsed time was 1 second.


 BTEQ -- Enter your SQL request or BTEQ command:


INSERT INTO CARLOS.PRUEBA01 VALUES (1,'UNO');


 *** Insert completed. One row added.
 *** Total elapsed time was 1 second.


 BTEQ -- Enter your SQL request or BTEQ command:
INSERT INTO CARLOS.PRUEBA01 VALUES (2,'DOS');


 *** Insert completed. One row added.
 *** Total elapsed time was 1 second.


 BTEQ -- Enter your SQL request or BTEQ command:
INSERT INTO CARLOS.PRUEBA01 VALUES (3,'TRES');


 *** Insert completed. One row added.
 *** Total elapsed time was 1 second.


 BTEQ -- Enter your SQL request or BTEQ command:


CREATE MULTISET TABLE CARLOS.PRUEBA02,
     NO FALLBACK ,
     NO BEFORE JOURNAL,
     NO AFTER JOURNAL,
     CHECKSUM = DEFAULT,
     DEFAULT MERGEBLOCKRATIO
     (
        ID_N  INTEGER     NOT NULL,
        C_TXT VARCHAR(15) NOT NULL
     )
     PRIMARY INDEX ( ID_N )
;


 *** Table has been created.
 *** Total elapsed time was 1 second.


 BTEQ -- Enter your SQL request or BTEQ command:


INSERT INTO CARLOS.PRUEBA02 VALUES (1,'RAS');


 *** Insert completed. One row added.
 *** Total elapsed time was 1 second.


 BTEQ -- Enter your SQL request or BTEQ command:
INSERT INTO CARLOS.PRUEBA02 VALUES (2,'DVA');


 *** Insert completed. One row added.
 *** Total elapsed time was 1 second.


 BTEQ -- Enter your SQL request or BTEQ command:
INSERT INTO CARLOS.PRUEBA02 VALUES (3,'TRI');


 *** Insert completed. One row added.
 *** Total elapsed time was 1 second.

Y ahora la ‘SELECT’ a la que hace referencia el título: “¿Cuántas tablas ves aquí?”

SELECT *
FROM CARLOS.PRUEBA01 t1,
CARLOS.PRUEBA02 t2
WHERE t1.ID_N = CARLOS.PRUEBA02.ID_N
;

La respuesta es clara ¿verdad?: Dos tablas.

Pues vamos a ver qué ocurre si ejecutamos la ‘query’:

 BTEQ -- Enter your SQL request or BTEQ command:


SELECT *
  FROM CARLOS.PRUEBA01 t1,
       CARLOS.PRUEBA02 t2
 WHERE t1.ID_N = CARLOS.PRUEBA02.ID_N
;


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

       ID_N  C_TXT                   ID_N  C_TXT
-----------  ---------------  -----------  ---------------
          2  DOS                        3  TRI
          2  DOS                        2  DVA
          2  DOS                        1  RAS
          3  TRES                       3  TRI
          3  TRES                       2  DVA
          3  TRES                       1  RAS
          1  UNO                        3  TRI
          1  UNO                        2  DVA
          1  UNO                        1  RAS

¿Qué es este resultado? ¿Cómo es posible que falle un ‘join’ tan sencillo?

Pues la respuesta a esta pregunta y a la que da nombre a este ‘post’ es que en realidad hay TRES tablas en el ‘join’, ya que al incluir el nombre completo de la segunda tabla en el ‘WHERE’ (t1.ID_N = CARLOS.PRUEBA02.ID_N) estamos implícitamente incluyendo la tabla PRUEBA02 una segunda vez y provocando un CROSS JOIN que es el causante de los resultados tan extraños (algo parecido a esto lo vimos aquí hace tiempo).

Por supuesto que todo se soluciona si en el ‘WHERE’ hacemos referencia a la columna de PRUEBA02 mediante el alias que hemos declarado (t2):

 BTEQ -- Enter your SQL request or BTEQ command:
 SELECT *
  FROM CARLOS.PRUEBA01 t1,
       CARLOS.PRUEBA02 t2
 WHERE t1.ID_N = t2.ID_N;


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

       ID_N  C_TXT                   ID_N  C_TXT
-----------  ---------------  -----------  ---------------
          3  TRES                       3  TRI
          2  DOS                        2  DVA
          1  UNO                        1  RAS

La moraleja del cuento: o usamos nombres cualificados completos o utilizamos alias, pero mejor no mezclarlos…

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: