90 Php. Otras Consultas
Upcoming SlideShare
Loading in...5
×
 

90 Php. Otras Consultas

on

  • 462 views

 

Statistics

Views

Total Views
462
Views on SlideShare
462
Embed Views
0

Actions

Likes
0
Downloads
13
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

90 Php. Otras Consultas 90 Php. Otras Consultas Document Transcript

  • Otras consultas Definición de tablas Estructura de tablas y relaciones Para desarrollar los ejemplos de este capítulo vamos a crear las tablas, cuyas estructuras En este ejemplo de tablas e interrelaciones que puedes ver en el código fuente siguiente: vinculadas con integridad relacional vamos a proponer la situación siguiente. <? $base="ejemplos"; Crearemos una primera tabla $c=mysql_connect ("localhost","pepe","pepa"); (alumnos) que va a contener mysql_select_db ($base, $c); datos personales de un grupo de ############################################### personas. # Creación de la tabla nombres con indice primario DNI Para evitar duplicar un mismo # tabla de nombres con índice primario en DNI alumno y alumnos sin DNI, vamos ############################################### a utilizar como índice primario $crear="CREATE TABLE IF NOT EXISTS alumnos ("; (PRIMARY KEY) el campo DNI (que $crear.="DNI CHAR(8) NOT NULL, "; es único para cada persona). $crear.="Nombre VARCHAR (20) NOT NULL, "; $crear.="Apellido1 VARCHAR (15) not null, "; La condición de que el campo DNI $crear.="Apellido2 VARCHAR (15) not null, "; sea PRIMARY KEY nos obliga a $crear.=" PRIMARY KEY(DNI) "; definirlo con el flag NOT NULL, $crear.=")"; dado que esta es una condición necesaria para la definición de $crear.=" Type=InnoDB"; índices primarios. if(mysql_query ($crear ,$c)){ print "tabla <b>nombres</b> creada<BR>"; Crearemos una segunda tabla }else{ (domicilios) con los domicilios de print "ha habido un error al crear la tabla <b>alumnos</b><BR>"; cada uno de los alumnos, } identificándolos también por su ############################################### DNI. Para evitar que un mismo # Creación de la tabla direcciones alumno pueda tener dos domicilios # tabla de nombres con índice único en DNI asignamos a al campo DNI de esta # para evitar dos direcciones al mismo alumno tabla la condición de índice único (UNIQUE). # y clave foránea nombres(DNI) # para evitar direcciones no asociadas a un alumno El índice UNIQUE podríamos # concreto. Se activa la opción de actualizar haberlo creado también como # en cascada y de borrar en cascada PRIMARY KEY ya que la única ############################################### diferencia de comportamiento $crear="CREATE TABLE IF NOT EXISTS domicilios ("; entre ambos es el hecho que aquel $crear.="DNI CHAR(8) NOT NULL, "; admitiría valores NULOS pero, $crear.="calle VARCHAR (20), "; dado que debemos evitar $crear.="poblacion VARCHAR (20), "; domicilios sin alumnos, insertaremos el flag NOT NULL en $crear.="distrito VARCHAR(5), "; este campo. $crear.=" UNIQUE identidad (DNI), "; $crear.="FOREIGN KEY (DNI) REFERENCES alumnos(DNI) "; El hecho de utilizar dos tablas no $crear.="ON DELETE CASCADE "; tiene otro sentido que la $crear.="ON UPDATE CASCADE "; ejemplificación ya que lo habitual $crear.=") TYPE = INNODB"; sería que todos los datos if(mysql_query ($crear ,$c)){ estuvieran en una misma tabla. print "tabla <b>domicilios</b> creada<br>"; Vincularemos ambas tablas de }else{ modo que no puedan crearse print "ha habido un error al crear la tabla <b>domicilios</b><BR>"; direcciones de alumnos } inexistentes y les pondremos la ############################################### opción de actualización y borrado # Creación de la tabla nombres con indice primario EVALUACIONES en cascada. De esta forma las # tabla de nombres con índice primario en NUMERO acciones en la tabla de alumno se ############################################### reflejarían automáticamente en la $crear="CREATE TABLE IF NOT EXISTS evaluaciones ("; tabla de domicilios. $crear.="NUMERO CHAR(1) NOT NULL, "; La tercera de las tablas $crear.="nombre_evaluacion VARCHAR (20) NOT NULL, "; (evaluaciones) tiene como $crear.=" PRIMARY KEY(NUMERO)"; finalidad definir las distintas $crear.=")"; evaluaciones que puede realizarse $crear.=" Type=InnoDB"; a cada alumno. Tendrá dos if(mysql_query ($crear ,$c)){ campos. Uno descriptivo (el print "tabla <b>evaluaciones</b> creada<BR>"; nombre de la evaluación) y otro }else{ identificativo (no nulo y único) que print "ha habido un error al crear la tabla <b>evaluaciones</b><BR>"; será tratado como PRIMARY KEY } para evitar duplicidades y porque, ############################################### además, va a ser utilizado como clave foránea en la tabla notas. # Creación de la tabla notas # indice UNICO para los campos DNI y evaluacion La tabla notas va a tener tres # con ello se impide calificar dos veces al mismo campos: DNI, nº de evaluación y # alumno en la misma evaluacion calificación. # claves foráneas (DOS) # el DNI de nombres para evitar calificar a alumnos inexistentes Estableceremos restricciones para # el NUMERO de la tabla evaluaciones para evitar calificar evitar que: # DOS VECES en una evaluación a un alumno ############################################### q Podamos calificar a un $crear="CREATE TABLE IF NOT EXISTS notas ("; alumno inexistente. $crear.="DNI CHAR(8) NOT NULL, "; q Podamos calificar una $crear.="evaluacion CHAR (1) NOT NULL, "; evaluación no incluida entre las previstas. $crear.="calificacion TINYINT (2), "; q Podamos poner más a cada /* observa que este indice primario está formado alumnos más de una por dos campos (DNI y evalucion) y que, como siempre calificación por evaluación. en el caso de PRIMARY KEY ambos son de tipo NOT NULL */ $crear.=" PRIMARY KEY vemaos(DNI,evaluacion), "; Creando una índice primario /* Fijate en la secuencia siguiente: formado por los campos DNI y 1º.- Creamos el índice evaluación evitaremos la última de 2º.- Establecemos la clave foránea
  • 3º.- Establecemo las condiciones ON DELETE las situaciones y añadiendo una 4º.- Establecemos las condiciones ON UPDTE vinculación con las tablas alumnos Es muy importe mantener esta secuencia para evitar y evaluaciones estaremos en condiciones de evitar las dos errores MySQL */ primeras. $crear.=" INDEX identico (DNI), "; $crear.="FOREIGN KEY (DNI) REFERENCES alumnos(DNI) "; En este gráfico puedes ver un $crear.="ON DELETE CASCADE "; esquema de la definición de estas $crear.="ON UPDATE CASCADE,"; tablas. /* Esta tabla tiene dos claves foráneas asociadas a dos tablas la anterior definida sobre alumnos como tabla principal y esta que incluimos a continuación asociada con evaluaciones Como ves repetimos la secuencia descrita anteriormente Es importante establecer estas definiciones de una en una (tal como ves en este ejemplo) y seguir la secuencia comentada anteriormente */ $crear.=" INDEX evalua (evaluacion),"; $crear.="FOREIGN KEY (evaluacion) REFERENCES evaluaciones(NUMERO) "; $crear.="ON DELETE CASCADE "; $crear.="ON UPDATE CASCADE"; $crear.=") TYPE = INNODB"; if(mysql_query ($crear ,$c)){ print "tabla <b>notas</b> creada <BR>"; }else{ print "ha habido un error al crear la tabla <b>notas</b><BR>"; echo mysql_error ($c)."<br>"; echo mysql_errno ($c); } mysql_close(); ?> Crear tablas ejemplo ¡Cuidado! Como puedes observar en la imagen de la izquierda, al definir la estructura de las tablas es muy importante prestar atención a que los campos vinculados sean del mismo tipo y dimensión. Observa también que los campos de referencia de los vínculos que se establecen (en las tablas primarias) tienen que ser definidos como PRIMARY KEY y que, por tanto, han de establecerse como no nulos (NOT NULL). Inserción de datos en tablas MySQL permite importar ficheros externos utilizando la siguiente sintaxis: LOAD DATA INFILE "nombre del fichero' [REPLACE | IGNORE] INTO TABLE nombre de la tabla Importación y exportación FIELDS de datos TERMINATED BY 'indicador de final de campo' ENCLOSED BY 'caracteres delimitadores de campos' Es esta una opción interesante por LINES la posibilidad que ofrece de STARTING BY 'caracteres indicadores de comienzo de registro' intercambiar datos entre diferentes TERMINATED BY 'caracteres indicadores del final de registro' fuentes y aplicaciones. En este ejemplo pueder un caso práctico de inserción de datos en las tablas creadas Importación de ficheros anteriormente. MySQL permite insertar en sus <? tablas los contenidos de ficheros $base="ejemplos"; de texto. Para ello utiliza la $c=mysql_connect ("localhost","pepe","pepa"); sentencia que tienes al margen y mysql_select_db ($base, $c); que detallaremos a continuación. # hemos creado un fichero de texto (datos_alumnos.txt) LOAD DATA INFILE # que contiene datos de algunos alumnos. Los diferentes Es un contenido obligatorio que # campos están entre comillas y separados unos de otros defina la opción de insertar datos # mediante un punto y coma. desde un fichero externo. # Cada uno de los registros comienza por un asterios # y los registros están separados por un salto de línes (rn) nombre del fichero # Incluimos estás especificaciones en la sentencia de inserción Se incluye inmediatamente if(mysql_query("LOAD DATA INFILE después de la anterior, es 'c:/Apache/htdocs/cursoPHP/datos_alumnos.txt' REPLACE obligatorio y debe contener (entre comillas) la ruta, el nombre y la INTO TABLE alumnos extensión del fichero que contiene FIELDS ENCLOSED BY '"' TERMINATED BY ';' los datos a insertar. LINES STARTING BY '*' TERMINATED BY 'rn' ",$c)){ print "Datos de alumnos cargados<br>"; [REPLACE|IGNORE] }else{ Es opcional. Si se omite se echo mysql_error ($c)."<br>"; producirá un mensaje de error si el echo mysql_errno ($c); fichero contiene valores iguales a } los contenidos en los campos de la # Para esta tabla usaremos el fichero datos_evaluaciones.txt tabla que no admiten duplicados. Con la opción REPLACE sustituiría # Los diferentes los valores existentes en la tabla y # campos están entre comillas y separados unos de otros con la opción IGNORE # mediante una coma. # Cada uno de los registros comienza por un espacio INTO TABLE nombre # y los registros están separados por un salto de línes (rn) Tiene carácter obligatorio y debe # Incluimos estás especificaciones en la sentencia de inserción
  • incluir como nombre el de la tabla if(mysql_query("LOAD DATA INFILE a la que se pretende agregar los 'c:/Apache/htdocs/cursoPHP/datos_evaluaciones.txt' REPLACE registros. INTO TABLE evaluaciones FIELDS FIELDS ENCLOSED BY ''' TERMINATED BY ',' Tiene carácter OPCIONAL y LINES STARTING BY ' ' TERMINATED BY 'rn' ",$c)){ permite incluir especificaciones print "Datos de evaluaciones cargados<br>"; sobre cuales son los caracteres }else{ delimitadores de campos y los que echo mysql_error ($c)."<br>"; indican el final del campo. Si se echo mysql_errno ($c); omite FIELDS no podrán incluirse } los ENCLOSED BY ni /* En este caso no incluimos especificación alguna. TERMINATED BY de campo. Bajo este suspuesto MySQL interpreta los valores por defecto ENCLOSED BY que son: los campos no van encerrados, las líneas no tienen Permite espeficar (encerrados ningún carácter indicador de comienzo, los campos están separados entre comillas) los caracteres mediante tabulaciones (carácter de escape t) y el final de línea delimitadores de los campos. Estos está señalado por un caracter de nueva línea (n) */ caracteres deberán encontrarse en if(mysql_query("LOAD DATA INFILE el fichero original al principio y al 'c:/Apache/htdocs/cursoPHP/datos_notas.txt' IGNORE final de los contenidos de cada INTO TABLE notas",$c)){ uno de los campos (por ejemplo, si print "Datos de notas cargados<br>"; el carácter fueran comillas los }else{ campos deberían aparecer así en echo mysql_error ($c)."<br>"; el fichero a importar algo como esto: "32.45"). Si se omite esta echo mysql_errno ($c); especificación (o se omite FIELDS) } se entenderá que los campos no /* Se comporta como los casos anteriores con distincos caracteres tienen caracteres para los diferentes eventos, tal como puedes ver en el código */ delimitadores. if(mysql_query("LOAD DATA INFILE 'c:/Apache/htdocs/cursoPHP/datos_domicilios.txt' IGNORE Cuando se incluyen como INTO TABLE domicilios delimitadores de campo las FIELDS ENCLOSED BY '|' TERMINATED BY '*' comillas (dobles o sencillas) es LINES STARTING BY '#' TERMINATED BY '}' ",$c)){ necesario utilizar una sintaxis como esta: '"' ó ''' de forma que print "Datos de domicilios cargados<br>"; no quepa la ambigüedad de si se }else{ trata de un carácter o de las echo mysql_error ($c)."<br>"; comillas de cierre de una cadena echo mysql_errno ($c); previamente abierta. }mysql_close(); ?> TERMINATED BY Se comporta de forma similar al anterior. Cargar datos Consultar tablas Permite qué caracteres son usados en el fichero original como separadores de campos (indicador Guardar datos en ficheros de final de campo). Si se omite, se interpretará con tal el carácter MySQL permite los contenidos de sus tablas a ficheros de texto. Para ello utiliza la tabulador (t). siguiente sintaxis: El uso de esta opción no requiere SELECT * INTO OUTFILE "nombre del fichero' que se especifique previamente FIELDS ENCLOSED BY pero si necesita que se haya incluido FIELDS. TERMINATED BY 'indicador de final de campo' LINES ENCLOSED BY 'caracteres delimitadores de campos' Si el fichero de datos contiene LINES caracteres (distintos de los valores STARTING BY 'caracteres indicadores de comienzo de registro' por defecto) para señalar el TERMINATED BY 'caracteres indicadores del final de registro' comienzo de un registro, el final FROM nombre de la tabla del mismo o ambos, debe incluirse este parámetro y, después de él, las especificaciones de esos <? valores correspondientes a: $base="ejemplos"; $c=mysql_connect ("localhost","pepe","pepa"); STARTING BY mysql_select_db ($base, $c); Permite especificar una carácter if(mysql_query ("SELECT * INTO OUTFILE como indicador de comienzo de un registro. Si se omite o se 'c:/Apache/htdocs/cursoPHP/alumnos.txt' especifica como '' se interpretará FIELDS ENCLOSED BY '"' TERMINATED BY ';' que no hay ningún carácter que LINES STARTING BY '*' TERMINATED BY 'rn' señale en comienzo de línea. FROM alumnos",$c)){ print "fichero alumnos.txt creado<br>"; TERMINATED BY }else{ Es el indicador del final de un echo mysql_error ($c)."<br>"; registro. Si se omite será echo mysql_errno ($c); considerado como un salto de línea } (n). if(mysql_query ("SELECT * INTO OUTFILE 'c:/Apache/htdocs/cursoPHP/domicilios.txt' Exportación de ficheros FIELDS ENCLOSED BY '|' TERMINATED BY '*' LINES STARTING BY '#' TERMINATED BY '}' Se comporta de forma similar al FROM domicilios",$c)){ supuesto anterior. Utiliza la print "fichero domicilios.txt creado<br>"; sintaxis siguiente: }else{ echo mysql_error ($c)."<br>"; SELECT * INTO OUTFILE echo mysql_errno ($c); Inicia la consulta de los campos } especificados después de SELECT (si se indica * realiza la consulta if(mysql_query ("SELECT * INTO OUTFILE sobre todos los campos y por el 'c:/Apache/htdocs/cursoPHP/notas.txt' orden en el que fue creada la FROM notas",$c)){ tabla) y redirige la salida a un print "fichero notas.txt creado<br>"; fichero. }else{ echo mysql_error ($c)."<br>"; nombre del fichero echo mysql_errno ($c); Es la ruta, nombre y extensión del } fichero en el que serán if(mysql_query ("SELECT * INTO OUTFILE almacenados los resultados de la consulta. 'c:/Apache/htdocs/cursoPHP/evaluaciones.txt' FIELDS ENCLOSED BY ''' TERMINATED BY ','
  • FIELDS LINES STARTING BY ' ' TERMINATED BY 'rn' ENCLOSED BY FROM evaluaciones",$c)){ TERMINATED BY print "fichero evaluaciones.txt creado<br>"; LINES }else{ STARTING BY TERMINATED BY echo mysql_error ($c)."<br>"; Igual que ocurría en el caso de echo mysql_errno ($c); importación de datos, estos } parámetros son opcionales. Si no mysql_close(); se especifican se incluirán los ?> valores por defecto. FROM nombre Crear ficheros de datos Su inclusión tiene carácter obligatorio. El valor de nombre ha de ser el de la tabla sobre la que ¡Cuidado! se realiza la consulta. Al exportar ficheros en entornos Windows, si se pretende que en el fichero de texto aparezca ¡Cuidado! un salto de línea no basta con utilizar la opción por defecto de LINES TERMINATED BY 'n' sino LINES TERMINATED BY 'rn' (salto de línea y retorno) que son los caracteres que Al importar ficheros habrá de necesita Windows para producir ese efecto. utilizarse el mismo formato Habrá de seguirse este mismo criterio cuando se trata de importar datos desde un fichero de con el que fueron creados texto. tanto FIELDS como LINES. Consultas de unión (JOIN) Consultas usando JOIN <? La claúsula JOIN es opción $base="ejemplos"; aplicable a consultas en tablas que $c=mysql_connect ("localhost","pepe","pepa"); tiene diversas opciones de uso. mysql_select_db ($base, $c); Iremos viéndolas de una en una. # vamos a crear un array con las diferente consultas Todas ellas han de ir incluidas # posteriormente lo leeremos y la ejecutaremos secuencialmente como parámetros de una consulta. Por tanto han de ir precedidas de: /* Devuelve todos los campos de ambas tablas. Cada registro de alumnos es asociado con todos los de domicilios*/ SELECT * $query[]="SELECT * FROM alumnos JOIN domicilios"; o de /* Devuelve todos los campos de ambas tablas. Cada registro de domicilios SELECT nom_tab.nom_cam,.. es asociado con todos los de alumnos */ donde nom_tab es un nombre de $query[]="SELECT * FROM domicilios JOIN alumnos"; tabla y nom_camp es el nombre /* Devuelve todos los campos de los registros de ambas tablas del campo de esa tabla que en los que coinciden los numeros del DNI*/ pretendemos visualizar para esa $query[]="SELECT * FROM alumnos JOIN domicilios consulta. Esta sintaxis es idéntica a la ya comentada en páginas ON domicilios.DNI=alumnos.DNI"; anteriores cuando tratábamos de /* Idéntica a la anterior. Solo se diferencia en que ahora consultas en varias tablas. se visualizan antes los campos domicilios*/ $query[]="SELECT * FROM domicilios JOIN alumnos Ahora veremos las diferentes ON domicilios.DNI=alumnos.DNI"; posibilidades de uso de JOIN /* devuelve cada uno de los registro de la tabla alumnos. Si existe un domicilio con igual DNI lo insertará. Si no existiera FROM tbl1 JOIN tbl2 insertará valores nulos en esos campos Suele definirse como el producto cartesiano de los elementos de la $query[]="SELECT * FROM alumnos LEFT JOIN domicilios primera tabla (tbl1) por lo de la ON domicilios.DNI=alumnos.DNI"; segunda (tbl2). /* Se comporta de forma idéntica al anterior. Ahora insertará todos los registros de domicilios Dicho de una forma más vulgar, y los alumnos coincidentes o en su defecto campos nulos.*/ esta consulta devuelve con $query[]="SELECT * FROM domicilios LEFT JOIN alumnos resultado una lista de cada uno de ON domicilios.DNI=alumnos.DNI"; los registros de los registros de la /* Al utilizar RIGHT será todos los registros de la tabla de la derecha primera tabla asociados (domicilios) los que aparezcan junto con las coincidencias o sucesivamente con todos los correspondientes a la segunda. Es junto a campos nulos. Aparecerán primero los campos de alumnos decir, aparecerá una línea y detrá los de domicilios*/ conteniendo el primer registro de $query[]="SELECT * FROM alumnos RIGHT JOIN domicilios la primera tabla seguido del ON (domicilios.DNI=alumnos.DNI AND alumnos.Nombre LIKE 'A%')"; primero de la segunda. A /* Consulta de nombre, apellido y localidad de todos los alumnos continuación ese mismo registro cuyo nombre empieza por A */ de la primera tabla acompañado $query[]="SELECT alumnos.Nombre, alumnos.Apellido1,alumnos.Apellido2, del segundo de la segunda tabla, y domicilios.poblacion FROM alumnos JOIN domicilios así, sucesivamente hasta acabar ON (domicilios.DNI=alumnos.DNI los registros de esa segunda tabla. AND alumnos.Nombre LIKE 'A%')"; En ese momento, repite el proceso # una consulta resumen de nos permitirá visualizar una lista con nombre con el segundo registro de la primera tabla y, nuevamente, # y apellidos de alumnos su dirección y localidad del domicilio todos los de la segunda. Así, # el nombre de la evaluación y su calificación. sucesivamente, hasta llegar al # Si no hay datos de población insertará ---- en vez del valor nulo último registro de la primera tabla # y si no hay calificación en una evaluación aparecerá N.P. asociado con el último de la # La consulta aparecerá agrupada por evaluaciones segunda. /* iniciamos el select especificando los campos de las diferentes tablas que prentendemos visualizar En total, devolverá un número de $q="(SELECT alumnos.Nombre,alumnos.Apellido1,"; líneas igual al resultado de $q.=" alumnos.Apellido2,domicilios.calle,"; multiplicar el número de registros de la primera tabla por los de la # al incluir IFNULL visualizaremos ---- en los campos cuyo resultado segunda. # sea nulo $q.=" IFNULL(domicilios.poblacion,'––––'),"; FROM tbl2 JOIN tbl1 $q.=" evaluaciones.nombre_evaluacion,"; Si permutamos la posición de las # con este IFNULL aparecerá N.P. en las evaluaciones no calificadas. tablas, tal como indicamos aquí, $q.=" IFNULL(notas.calificacion,'N.P.')"; obtendremos el mismo resultado # especificamos el primer JOIN con el que tendremos como resultado una que en el caso anterior pero, como lista es lógico pensar, con una # de todos los alumnos con sus direcciones correspondientes ordenación diferente de los resultados. # por efecto de la clausula ON. # Al poner LEFT se incluirían los alumnos que no tuvieran FROM tbl2 JOIN tbl1 ON cond # su dirección registrada en la tabla de direccione El parámetro ON permite añadir $q.=" FROM (alumnos LEFT JOIN domicilios"; una condición (cond)a la consulta
  • $q.=" ON alumnos.DNI=domicilios.DNI)"; de unión. Su comportamiento es # al unir por la izquierda con notas tendríamos todos los resultados idéntico al de WHERE en las # del JOIN anterior asociados con con todas sus calificaciones consultas ya estudiadas y permite # por efecto de la claúsula ON el uso de las mismas procedimientos de establecimiento $q.=" LEFT JOIN notas ON notas.DNI=alumnos.DNI"; de condiciones que aquel operador. # 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 FROM tbl1 LEFT JOIN tbl2 ON # con todos los campos de la tabla evaluaciones con lo que resultaría cond # una lista de todos los alumnos con todas las calificaciones Cuando se incluye la cláusula LEFT # incluyendo un campo en blanco (sería sustituido por N.P:) delante de JOIN el resultado de la # en aquellas que no tuvieran calificación registrada consulta es el siguiente: $q.=" RIGHT JOIN evaluaciones"; – Devolvería cada uno los registros $q.=" ON evaluaciones.NUMERO=notas.evaluacion"; de la tabla especificada a la izquierda de LEFT JOIN -sin /* la clausula WHERE nos permite restringir los resultados a los valores considerar las restricciones que correspondientes únicamente a la evaluación número 1*/ puedan haberse establecido en las $q.=" WHERE evaluaciones.NUMERO=1)"; claúsulas ON para los valores de # cerramos la consulta anterior con el paréntesis. Observa que lo esa tabla– asociándolos con # hemos abierto delante del SELECT e insertamos UNION ALL aquellos de la otra tabla que # para que el resultado de la consulta anterior aparezca cumplan las condiciones # seguido del correspondiente a la incluida después de UNION ALL establecidas en la claúsula ON. Si $q.=" UNION ALL"; ningún registro de la segunda #iniciamos (también con paréntesis) la segunda consulta tabla cumpliera la condición # que será identica a la anterior salvo el WHERE devolvería valores nulos. # será modificado para extraer datos de la evaluación nº2 FROM tbl1 RIGHT JOIN tbl2 ON $q.="(SELECT alumnos.Nombre,alumnos.Apellido1,"; cond $q.=" alumnos.Apellido2,domicilios.calle,"; Se comporta de forma similar al $q.=" IFNULL(domicilios.poblacion,'––––'),"; anterior. Ahora los posibles valores $q.=" evaluaciones.nombre_evaluacion,"; nulos serán asignados a la tabla $q.=" IFNULL(notas.calificacion,'N.P.')"; indicada a la izquierde de RIGHT $q.=" FROM (alumnos LEFT JOIN domicilios"; JOIN y se visualizarían todos los $q.=" ON alumnos.DNI=domicilios.DNI)"; registros de la tabla indicada a la $q.=" LEFT JOIN notas ON notas.DNI=alumnos.DNI"; derecha. $q.=" RIGHT JOIN evaluaciones"; $q.=" ON evaluaciones.NUMERO=notas.evaluacion"; JOIN múltiples $q.=" WHERE evaluaciones.NUMERO=2)"; # hemos cerrado el parentesis de la consulta anterior Tal como puedes observar en el # e incluimos un nuevo UNION ALL para consultar los datos ejemplo, es perfectamente factible # correspondientes a la tercera evaluación utilizar conjuntamente varios JOIN, $q.=" UNION ALL"; LEFT JOIN y RIGHT JOIN. Las $q.="(SELECT alumnos.Nombre,alumnos.Apellido1,"; diferentes uniones irán $q.=" alumnos.Apellido2,domicilios.calle,"; ejecutándose de izquierda a $q.=" IFNULL(domicilios.poblacion,'––––'),"; derecha (según el orden en el que $q.=" evaluaciones.nombre_evaluacion,"; estén incluidos en la sentencia) y $q.=" IFNULL(notas.calificacion,'N.P.')"; el resultado del primero será $q.=" FROM (alumnos LEFT JOIN domicilios"; utilizado para la segunda unión y así sucesivamente. $q.=" ON alumnos.DNI=domicilios.DNI)"; $q.=" LEFT JOIN notas ON notas.DNI=alumnos.DNI"; En cualquier caso, es posible $q.=" RIGHT JOIN evaluaciones"; alterar ese orden de ejecución $q.=" ON evaluaciones.NUMERO=notas.evaluacion"; estableciendo otras prioridades $q.=" WHERE evaluaciones.NUMERO=3)"; mediante paréntesis. # incluimos la variable $q en el array de consultas $query[]=$q; UNION de consultas # 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 MySQL permite juntar en una sola salida los resultados de varias # y la cadena que contiene las sentencias de dicha consulta consultas. La sintaxis es la foreach($query as $v){ siguiente: visualiza(mysql_query($v,$c),$v); } (SELECT ...) function visualiza($resultado,$query){ UNION ALL PRINT "<BR><BR><i>Resultado de la sentencia:</i><br>"; (SELECT ...) print "<b><font color=#ff0000>"; UNION ALL print $query."</font></b><br><br>"; (SELECT ...) PRINT "<table align=center border=2>"; Cada uno de los SELECT ha de ir while ($registro = mysql_fetch_row($resultado)){ encerrado entre paréntesis. echo "<tr>"; foreach($registro as $valor){ echo "<td>",$valor,"</td>"; } } echo "</table><br>"; } ?> Ejecutar script Anterior Indice Siguiente