Lección 12 - El producto cartesiano (SQL FROM)

Curso SQL para principiantes


Si usted durante su infancia jugó a vestir muñecas, recordará que el juego consistía en un conjunto de camisetas y otro de pantalones de manera que, combinando un elemento de cada conjunto, podían confeccionarse distintas mudas con las que vestir la muñeca.



Es más que probable conociendo a los niños que, si es el caso, usted realizara el producto cartesiano de estos dos conjuntos, es decir, el producto cartesiano de las camisetas con los pantalones. Para ello debió vestir la muñeca, al menos una vez, con todas y cada una de las combinaciones posibles, de modo que todas las camisetas se combinaron con todos los pantalones, y por ende, todos los pantalones con las camisetas. El conjunto resultante de pares de elementos posibles es el producto cartesiano de ambos conjuntos.
Si suponemos que el número de camisetas era de cinco elementos y el de pantalones de cuatro, entonces las combinaciones posibles son veinte (5 x 4), ya que para cada camiseta tenemos cuatro mudas distintas, una con cada pantalón. Esos veinte pares de elementos son los veinte elementos del conjunto resultante. Por tanto el producto cartesiano entre dos conjuntos da como resultado un nuevo conjunto con tantos elementos como pares posibles de elementos puedan combinarse.

* * *

Si trasladamos esto al ámbito que nos ocupa de las bases de datos, una tabla es en realidad un conjunto de registros, y al realizar una consulta como la siguiente:

Código: Seleccionar todo
select *
  from TABLA1 , TABLA2


el motor SQL realiza el producto cartesiano de ambos conjuntos, combinando todos los elementos o registros de la TABLA1 con todos los registros de la TABLA2, de manera que cada fila de resultado es una de las combinaciones posibles. Por tanto el número de filas resultantes será igual al número de registros de la TABLA1 multiplicado por el número de registros de la TABLA2.

Para ilustrar esto vamos a considerar estas dos tablas:

Tabla CAMISAS:


Tabla PANTALONES:


En estas tablas se guardan el vestuario de camisas y pantalones por separado, cada prenda tiene un número que la identifica y un peso expresado en gramos.
Si ahora nos preguntamos lo siguiente: ¿Qué combinaciones ofrece este vestuario? La respuesta es el producto cartesiano de ambas tablas:

Código: Seleccionar todo
select *
  from CAMISAS , PANTALONES


Al intervenir dos tablas en una consulta SQL, en la cláusula SELECT se pueden solicitar datos de cualquiera de las dos tablas. En el ejemplo anterior se indica un asterisco, de modo que el motor SQL devuelve todos los campos de la primera tabla, seguido de todos los campos de las segunda tabla.

Veamos un poco como ejecuta esta consulta el motor SQL: primero escoge la tabla CAMISAS y toma el primer registro, con él recorre toda la tabla PANTALONES asociandole todos los registros de la tabla PANTALONES. Acto seguido tomará el segundo registro de la tabla CAMISAS y repetirá la operación asociando a este todos los registros de la tabla PANTALONES. Y así irá repitiendo esta operación con todos los registros de la tabla CAMISAS hasta llegar al último. Por tanto recorrerá la tabla PANTALONES tantas veces como registros hay en la tabla CAMISAS.

Para eliminar las columnas que no interesan construimos la siguiente consulta SQL:
Código: Seleccionar todo
select CAMISA , PANTALON
  from CAMISAS 
, PANTALONES



Campo ambiguo
La ambigüedad se da cuando en una consulta SQL de por ejemplo dos tablas, en ambas existen uno o más campos con el mismo nombre, y estos campos aparecen en cualquier cláusula de la consulta. Ningún SGBD es hasta ahora adivino, por lo que si no le indicamos a cual de las tabla pertenece el campo al que hacemos mención, devolverá un error.

Para ilustrar lo que es un campo ambiguo en una consulta SQL, planteamos la siguiente cuestión, ¿qué mudas pueden confeccionarse con este vestuario y que pesa en conjunto cada muda, es decir, pantalón más camisa?

La solución pasa por sumar el peso de la camisa más el del pantalón, ese dato se guarda en un campo que se denomina igual en ambas tablas: PESO_GR, por lo que debe indicarse a que tabla pertenece cada campo PESO_GR que aparezca en la consulta. Esto se consigue precediendo al campo por el nombre de la tabla, separando la tabla del campo por un punto:

Código: Seleccionar todo
select CAMISA , PANTALON , CAMISAS.PESO_GR + PANTALONES.PESO_GR as PESO_MUDA
  from CAMISAS 
, PANTALONES


Sugerencia: Lleve la anterior consulta al banco de pruebas y elimine la tabla y el punto que preceden a cualquiera de los dos campos PESO_GR que intervienen.

En realidad esto se debería abordar al revés. En general en una consulta SQL con más de una tabla debe indicarse siempre a que tabla pertenece cada campo, pudiendo no hacerse en el caso de que no exista ambigüedad, aunque no se recomienda. Las tablas pueden cambiar en un futuro, y donde no existe ambigüedad hoy, puede no ser así mañana. Por tanto es más prudente para evitar fuentes de errores futuras construir la anterior consulta así:

Código: Seleccionar todo
select CAMISAS.CAMISA , PANTALONES.PANTALON , CAMISAS.PESO_GR + PANTALONES.PESO_GR as PESO_MUDA
  from CAMISAS 
, PANTALONES


Alias de tabla
Al igual que el SQL permite rebautizar columnas de la cláusula SELECT, también permite rebautizar tablas de la cláusula FROM. Para ello se emplea de igual modo la palabra clave AS. Se consigue así que las consultas sean menos laboriosas de construir, menos tupidas y más simplificadas a la vista del desarrollador. Por ejemplo:

Código: Seleccionar todo
select C.CAMISA , P.PANTALON , C.PESO_GR + P.PESO_GR as PESO_MUDA
  from CAMISAS as C
, PANTALONES as P


Al igual que con los alias de campo, no es necesario indicar la palabra clave AS para establecer un alias, si la omitimos el SGBD entiende de igual modo que la palabra que sigue a la tabla o al campo es un alias. Lleve la anterior consulta al banco de pruebas y elimine las palabras clave AS tanto de la cláusula SELECT como de la cláusula FROM, dejando un espacio entre la tabla y su alias, observará que el resultado es el mismo.


* * *

¿Qué ocurre si cruzamos tres tablas en una misma consulta SQL?
Si intuitivamente usted cree que el motor SQL realizará el producto cartesiano de tres tablas esta en lo cierto. Tomemos la tabla CALZADOS:

Es de esperar que si a la consulta SQL de las camisas con los pantalones le añadimos esta tabla, el motor SQL realice el producto cartesiano sobre estos dos conjuntos, es decir, sobre el conjunto de las camisas-pantalones(6 elementos) y el conjunto de los calzados:
Código: Seleccionar todo
select *
  from CAMISAS , PANTALONES , CALZADOS




Las combinaciones o registros resultantes es igual a la multiplicación del número de camisas por el número de pantalones por el número de calzados: (3 x 2) x 3 = 6 x 3 = 18

Realicemos la consulta que devolvía las distintas mudas con su peso, considerando también la tabla CALZADOS:
Código: Seleccionar todo
  select C.CAMISA , P.PANTALON , Z.CALZADO , C.PESO_GR + P.PESO_GR + Z.PESO_GR as PESO_MUDA
    from CAMISAS C 
, PANTALONES P , CALZADOS Z
order by C
.ID_CAMISA , P.ID_PANTALON , Z.ID_CALZADO




* * *

Para acabar esta lección y a modo de adelanto, fíjese en las filas resultantes de la anterior consulta SQL, usted que es el informático no tendrá problemas en saber que el resultado son en realidad las distintas mudas que se pueden confeccionar con el vestuario disponible y el peso de cada una. Pero créame, su jefe se lo agradecerá si le muestra el resultado así:

Código: Seleccionar todo
  select concat('Camisa de ' , C.CAMISA , ' con pantalón de ' , P.PANTALON , ' y ' , Z.CALZADO) as MUDA , 
         C
.PESO_GR + P.PESO_GR + Z.PESO_GR PESO_MUDA
    from CAMISAS C 
, PANTALONES P , CALZADOS Z
order by C
.ID_CAMISA , P.ID_PANTALON , Z.ID_CALZADO



CONCAT es una función que concatena datos de tipo cadena dando como resultado una única cadena. No debe confundirse esta función con las funciones de totalización (SUM , AVG ....). Las funciones se tratarán más adelante, por el momento no se preocupe por ello y quédese con la idea. Añadir también que la función CONCAT es un recurso particular del SGBD MySQL fuera del estándar SQL, por ejemplo en Oracle el modo de concatenar cadenas aplicado a este ejemplo es el siguiente:
Código: Seleccionar todo
select 'Camisa de ' || C.CAMISA || ' con pantalón de ' || P.PANTALON as MUDA
  from CAMISAS C
, PANTALONES P



* * *

Resumen
En las consultas SQL de dos o más tablas:

  • Sin cláusula WHERE el motor SQL realiza el producto cartesiano de todas las tablas.

  • Para evitar la ambigüedad de campos y por tanto asegurar el funcionamiento de la consulta SQL, debe indicarse para cualquier campo que aparezca en la consulta y en cualquiera de sus cláusulas, la tabla a la que pertenece del siguiente modo: TABLA.CAMPO

  • Es posible establecer alias o sobrenombres de tabla, con intención de agilizar la construcción de la consulta, y usar ese alias para indicar a que tabla pertenece cada campo.

* * *

Ejercicio 1
Realice una consulta que devuelva las combinaciones posibles entre los pantalones y los calzados, sin más columnas que la descripción de cada prenda. Use alias de tabla para indicar a que tabla pertenece cada campo de la cláusula SELECT.

Ejercicio 2
Si en una BD existe una tabla T1 con 4 campos y 12 registros, y una tabla T2 con 7 campos y 10 registros, ¿cuantas filas y columnas devolvería la siguiente consulta?
Código: Seleccionar todo
select *
  from T1 , T2





    Lección 11 - Síntesis de la primera parte
  • Lección 13 - Consultas III (SQL SELECT FROM WHERE)

Creative Commons License Creative Commons License

Este curso está sujeto a la licencia Reconocimiento-NoComercial-SinObraDerivada 3.0 de Creative Commons. Usted puede copiarla, distribuirla y comunicarla públicamente siempre que especifique su autor y deletesql.com; no la utilice para fines comerciales; y no haga con ella obra derivada. Puede usted consultar la licencia completa aquí.




Volver a Curso SQL desde cero

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 6 invitados