You are on page 1of 5

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
###############################################
● Podamos calificar a un $crear="CREATE TABLE IF NOT EXISTS notas (";
alumno inexistente. $crear.="DNI CHAR(8) NOT NULL, ";
● Podamos calificar una
$crear.="evaluacion CHAR (1) NOT NULL, ";
evaluación no incluida entre
las previstas.
$crear.="calificacion TINYINT (2), ";
● 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 (\r\n)
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 '\r\n' ",$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 (\r\n)
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 '\r\n' ",$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 '\r\n'
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 '\r\n'
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 '\r\n' (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

You might also like