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:
- – Devolvería cada uno los registros de la tabla especificada a la izquierda de LEFT JOIN –sin considerar las restricciones que puedan haberse establecido en las claúsulas ON para los valores de esa tabla– asociándolos con aquellos de la otra tabla que cumplan las condiciones establecidas en la claúsula ON. Si ningún registro de la segunda tabla cumpliera la condición devolvería valores nulos.
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>"; } ?>
0 comentarios:
Publicar un comentario