Ver índice
Consultas de unión

        Ocultar índice  

   Índice de contenidos
   Instalación en Windows
   Instalación en Ubuntu
   Servidores seguros
   Páginas dinámicas
   Sintaxis básica
   Operaciones
   Arrays
   Formatos de presentación
   Operadores
   Bucles
   Extraer y ord. información
   Funciones
   Ficheros externos
   Imágenes dinámicas
   Gestión de directorios
   Cookies y sesiones
   Clases y objetos
   Ficheros en formato PDF
   Bases de datos MySQL
   PHP y XML
   PDO - Bases SQLite / MySQL
   MySQL a traves de misqli
   Algo de JavaScript y AJAX


Consultas usando JOIN

La claúsula JOIN es opción aplicable a consultas en tablas que tiene diversas opciones de uso. Iremos viéndolas de una en una. Todas ellas han de ir incluidas como parámetros de una consulta. Por tanto han de ir precedidas de:

SELECT *
o de
SELECT nombre_tabla.nombre_campo,..

donde nombre_tabla es un nombre de tabla y nombre_campo es el nombre del campo de esa tabla que pretendemos visualizar para esa consulta. Esta sintaxis es idéntica a la ya comentada en páginas anteriores cuando tratábamos de consultas en varias tablas.

Ahora veremos las diferentes posibilidades de uso de JOIN

FROM tabla1 JOIN tabla2

Suele definirse como el producto cartesiano de los elementos de la primera tabla (tabla1) por lo de la segunda (tabla2).

Dicho de una forma más vulgar, esta consulta devuelve con resultado una lista de cada uno de los registros de la primera tabla asociados sucesivamente con todos los correspondientes a la segunda. Es decir, aparecerá una línea conteniendo el primer registro de la primera tabla seguido del primero de la segunda. A continuación, ese mismo registro de la primera tabla acompañado del segundo de la segunda tabla, y así, sucesivamente hasta acabar los registros de esa segunda tabla. En ese momento, repite el proceso con el segundo registro de la primera tabla y, nuevamente, todos los de la segunda. Así, sucesivamente, hasta llegar al último registro de la primera tabla asociado con el último de la segunda.

En total, devolverá un número de líneas igual al resultado de multiplicar el número de registros de la primera tabla por los de la segunda.

FROM tabla2 JOIN tabla1

Si permutamos la posición de las tablas, tal como indicamos aquí, obtendremos el mismo resultado que en el caso anterior pero, como es lógico pensar, con una ordenación diferente de los resultados.

FROM tabla2 JOIN tabla1 ON condicion

El parámetro ON permite añadir una condición (condicion) a la consulta de unión. Su comportamiento es idéntico al de WHERE en las consultas ya estudiadas y permite el uso de las mismas procedimientos de establecimiento de condiciones que aquel operador.

FROM tabla1 LEFT JOIN tabla2 ON condicion

Cuando se incluye la cláusula LEFT delante de JOIN el resultado de la consulta es el siguiente:


FROM tabla1 RIGHT JOIN tabla2 ON condicion

Se comporta de forma similar al anterior. Ahora los posibles valores nulos serán asignados a la tabla indicada a la izquierde de RIGHT JOIN y se visualizarían todos los registros de la tabla indicada a la derecha.

JOIN múltiples

Tal como puedes observar en el ejemplo, es perfectamente factible utilizar conjuntamente varios JOIN, LEFT JOIN y RIGHT JOIN. Las diferentes uniones irán ejecutándose de izquierda a derecha (según el orden en el que estén incluidos en la sentencia) y el resultado del primero será utilizado para la segunda unión y así sucesivamente.

En cualquier caso, es posible alterar ese orden de ejecución estableciendo otras prioridades mediante paréntesis.

UNION de consultas

MySQL permite juntar en una sola salida los resultados de varias consultas. La sintaxis es la siguiente:

(SELECT ...)
UNION ALL
(SELECT ...)
UNION ALL
(SELECT ...)

Cada uno de los SELECT ha de ir encerrado entre paréntesis.

Ejemplo de consultas de unión (JOIN)
<?php
$base="ejemplos";
$c=mysql_connect ("localhost","pepe","pepa");
mysql_select_db ($base, $c);
# vamos a crear un array con las diferente consultas
# posteriormente lo leeremos y la ejecutaremos secuencialmente
/* Devuelve todos los campos de ambas tablas.
  Cada registro de alumnos es asociado con todos los de domicilios*/
$query[]="SELECT * FROM alumnos JOIN domicilios";
/* Devuelve todos los campos de ambas tablas. Cada registro de domicilios
   es asociado con todos los de alumnos */
$query[]="SELECT * FROM domicilios JOIN alumnos";
/* Devuelve todos los campos de los registros de ambas tablas
en los que coinciden los numeros del DNI*/
$query[]="SELECT * FROM alumnos JOIN domicilios
                        ON domicilios.DNI=alumnos.DNI";
/* Idéntica a la anterior. Solo se diferencia en que ahora
se visualizan antes los campos domicilios*/
$query[]="SELECT * FROM domicilios JOIN alumnos
                        ON domicilios.DNI=alumnos.DNI";
/* devuelve cada uno de los registro de la tabla alumnos. Si existe
   un domicilio con igual DNI lo insertará. Si no existiera
   insertará valores nulos en esos campos
$query[]="SELECT * FROM alumnos LEFT JOIN domicilios
                        ON domicilios.DNI=alumnos.DNI";
/* Se comporta de forma idéntica al anterior.
   Ahora insertará todos los registros  de domicilios
   y los alumnos coincidentes o en su defecto campos nulos.*/
$query[]="SELECT * FROM domicilios LEFT JOIN alumnos
                        ON domicilios.DNI=alumnos.DNI";
/* Al utilizar RIGHT será todos los registros de la tabla de la derecha
(domicilios) los que aparezcan junto con las coincidencias o
junto a campos nulos. Aparecerán primero los campos de alumnos
y detrá los de domicilios*/
$query[]="SELECT * FROM alumnos RIGHT JOIN domicilios
           ON (domicilios.DNI=alumnos.DNI AND alumnos.Nombre LIKE 'A%')";
/* Consulta de nombre, apellido y localidad de todos los alumnos
cuyo nombre empieza por A */
$query[]="SELECT alumnos.Nombre, alumnos.Apellido1,alumnos.Apellido2,
         domicilios.poblacion FROM alumnos JOIN domicilios
                        ON (domicilios.DNI=alumnos.DNI
                        AND alumnos.Nombre LIKE 'A%')";
# una consulta resumen de nos permitirá visualizar una lista con nombre
# y apellidos de alumnos su dirección y localidad del domicilio
# el nombre de la evaluación y su calificación.
# Si no hay datos de población insertará ---- en vez del valor nulo
# y si no hay calificación en una evaluación aparecerá N.P.
# La consulta aparecerá agrupada por evaluaciones
/* iniciamos el select especificando los campos de las diferentes
   tablas que prentendemos visualizar  */
$q="(SELECT alumnos.Nombre,alumnos.Apellido1,";
$q.=" alumnos.Apellido2,domicilios.calle,";
# al incluir IFNULL visualizaremos ---- en los campos cuyo resultado
# sea nulo
$q.=" IFNULL(domicilios.poblacion,'––––'),";
$q.=" evaluaciones.nombre_evaluacion,";
# con este IFNULL aparecerá N.P. en las evaluaciones no calificadas.
$q.=" IFNULL(notas.calificacion,'N.P.')";
# especificamos el primer JOIN con el que tendremos como resultado una lista
# de todos los alumnos con sus direcciones correspondientes
# por efecto de la clausula ON.
# Al poner LEFT se incluirían los alumnos que no tuvieran
# su dirección registrada en la tabla de direccione
$q.=" FROM (alumnos LEFT JOIN domicilios";
$q.="        ON alumnos.DNI=domicilios.DNI)";
# al unir por la izquierda con notas tendríamos todos los resultados
# del JOIN anterior asociados con con todas sus calificaciones
# por efecto de la claúsula ON
$q.="         LEFT JOIN notas ON notas.DNI=alumnos.DNI";
# al añadir esta nueva unión por la DERECHA con la tabla evaluaciones
# se asociaría cada uno de los resultados de las uniones anteriores
# con todos los campos de la tabla evaluaciones con lo que resultaría
# una lista de todos los alumnos con todas las calificaciones
# incluyendo un campo en blanco (sería sustituido por N.P:)
# en aquellas que no tuvieran calificación registrada
$q.="         RIGHT JOIN evaluaciones";
$q.="         ON evaluaciones.NUMERO=notas.evaluacion ";
/* la clausula WHERE nos permite restringir los resultados a los valores
 correspondientes únicamente a la evaluación número 1*/
$q.="              WHERE evaluaciones.NUMERO=1)";
# cerramos la consulta anterior con el paréntesis. Observa que lo
# hemos abierto delante del SELECT e insertamos UNION ALL
# para que el resultado de la consulta anterior aparezca
# seguido del correspondiente a la incluida después de UNION ALL
$q.=" UNION ALL";
#iniciamos (también con paréntesis) la segunda consulta
# que será identica a la anterior salvo el WHERE
# será modificado para extraer datos de la evaluación nº2
$q.="(SELECT alumnos.Nombre,alumnos.Apellido1,";
$q.=" alumnos.Apellido2,domicilios.calle,";
$q.=" IFNULL(domicilios.poblacion,'––––'),";
$q.=" evaluaciones.nombre_evaluacion,";
$q.=" IFNULL(notas.calificacion,'N.P.')";
$q.=" FROM (alumnos LEFT JOIN domicilios";
$q.=" ON alumnos.DNI=domicilios.DNI)";
$q.=" LEFT JOIN notas ON notas.DNI=alumnos.DNI";
$q.=" RIGHT JOIN evaluaciones";
$q.=" ON evaluaciones.NUMERO=notas.evaluacion";
$q.=" WHERE evaluaciones.NUMERO=2)";
# hemos cerrado el parentesis de la consulta anterior
# e incluimos un nuevo UNION ALL para consultar los datos
# correspondientes a la tercera evaluación
$q.=" UNION ALL";
$q.="(SELECT alumnos.Nombre,alumnos.Apellido1,";
$q.=" alumnos.Apellido2,domicilios.calle,";
$q.=" IFNULL(domicilios.poblacion,'––––'),";
$q.=" evaluaciones.nombre_evaluacion,";
$q.=" IFNULL(notas.calificacion,'N.P.')";
$q.=" FROM (alumnos LEFT JOIN domicilios";
$q.=" ON alumnos.DNI=domicilios.DNI)";
$q.=" LEFT JOIN notas ON notas.DNI=alumnos.DNI";
$q.=" RIGHT JOIN evaluaciones";
$q.=" ON evaluaciones.NUMERO=notas.evaluacion";
$q.=" WHERE evaluaciones.NUMERO=3)";
# incluimos la variable $q en el array de consultas
$query[]=$q;
# leemos el array y visualizamos el resultado
# cada consulta a traves de la llamada a la funcion visualiza
# a la que pasamos el resultado de la consulta
# y la cadena que contiene las sentencias de dicha consulta
foreach($query as $v){
    visualiza(mysql_query($v,$c),$v);
}
function visualiza($resultado,$query){
	   PRINT "<BR><BR><i>Resultado de la sentencia:</i><br>";
	   print "<b><font color=#ff0000>";
	   print $query."</font></b><br><br>";
       PRINT "<table align=center border=2>";
          while ($registro = mysql_fetch_row($resultado)){
               echo "<tr>";
               foreach($registro  as $valor){
                     echo "<td>",$valor,"</td>";
               }
         }
       echo "</table><br>";
}
?>
Ejecutar script