Modelo ER de la base de datos CAMPEONATO
El modelo ER de la base de datos campeonato es el siguiente:
En la unidad anterior Noiba y Vindio han dejado lista la base de datos que le encargaron en Talleres Faber, sobre un taller mecánico, para empezar a introducir la información en las tablas, de forma que se pueda acceder a los datos como si de una sola tabla se tratara. En este momento ha acabado la primera parte de su proyecto y quieren mostrar el resultado.
La empresa ha crecido mucho desde que empezó su actividad como un pequeño taller mecánico que reparaba los vehículos de los vecinos del barrio.
Actualmente tiene varios empleados y el número de clientes es cada vez mayor.
Los socios de la empresa están deseando ver cómo el trabajo de Noiba y Vindio simplifican las tareas de gestión y organización, y quieren comprobar que ofrece todas las prestaciones adicionales que habían prometido.
Una de las cosas más importantes que ofrece una base de datos es la opción de poder consultar los datos que guarda, por eso Noiba y Vindio van a intentar sacar el máximo partido a las tablas que han guardado y sobre ellas van a obtener toda aquella información que su cliente les ha solicitado. Sabemos que dependiendo de quién consulte la base de datos, se debe ofrecer un tipo de información u otra. Es por esto que deben crear distintas consultas y vistas.
En esta unidad aprenderemos a extraer la información de una base de datos estableciendo los requisitos y criterios para seleccionar los datos.
Por lo que has estudiado en unidades anteriores, conoces las ventajas que ofrece un SGBD, pero también sabes que si no conocemos la forma de relacionarnos con la base de datos, la información puede estar “disponible” pero no podremos acceder a ella.
El SGBD va a ser capaz, a partir de las instrucciones, de hacer consultas enlazando las tablas mediante las relaciones definidas en el diseño y en la creación. Por eso es tan importante que todo se haya hecho respetando los criterios establecidos por el modelo, tanto en la fase de diseño lógico como físico. De no hacerlo así nos podríamos encontrar con que, una vez realizado todo el trabajo y después de registrar los datos en las tablas, no tenemos acceso a lo que buscamos o que la información devuelta por las consultas resulta incoherente.
El siguiente paso sería introducir los datos en las tablas, pero para facilitar la comprensión del proceso vamos a partir de una base de datos ya creada y que contenga información. Explicaremos a continuación como hacer consultas en ella, tanto desde herramientas gráficas como utilizando el lenguaje SQL.
Noiba y Vindio saben que para conseguir el acceso a los datos es muy importante conocer bien:
Pues bien, vamos a revisar con ella las herramientas gráficas que se utilizan con algunos SGBD muy conocidos como: asistentes para realizar consultas, entornos para introducir consultas en modo diseño, editores para crear nuestras sentencias en SQL etc.
Como sabemos un SGBD integra, además de la base de datos, un conjunto de herramientas que nos facilitan el diseño, la gestión y la administración de la base de datos.
En unidades anteriores hemos visto cómo algunas de esas herramientas nos pueden ayudar a establecer tanto el diseño lógico como el diseño físico de la base de datos. En el caso de las consultas también contamos cada vez con un mayor número de utilidades.
Podemos hacer una clasificación de estas herramientas en dos tipos:
A continuación veremos algunos ejemplos de los distintos tipos de herramientas que hemos citado, teniendo en cuenta que se trata de un pequeño ejemplo de las numerosas herramientas presentes en el mercado, tanto de software libre como propietario.
A lo largo de esta unidad realizaremos numerosos ejercicios para aprender a manejar el lenguaje SQL. Como base de la mayoría de los ejercicios usaremos la base de datos denominada <strong>CAMPEONATO</strong>, que tendrás que desplegar en tu servidor MySQL. Te indicamos a continuación el modelo y script SQL de la base de datos y la forma de instalarla en tu servidor MySQL.
Como cliente de MySQL, puedes usar la línea de comandos o cualquier cliente gráfico, como por ejemplo Workbench.
A continuación vemos:
El modelo ER de la base de datos campeonato es el siguiente:
El modelo relacional correspondiente a la base de datos campeonato es el siguiente: te mostramos el modelo textual a la izquierda y de forma gráfica a la derecha (elaborado con la herramienta de modelado de Workbench).
En el modelo textual se ha indicado la restricción de cada claveajena o foránea en cuanto a los borrados y las modificaicones:
Todas las consultas de ejemplo sobre la base de datos CAMPEONATO y las que se piden en los ejercicios deben probarse sobre el servidor MySQL. Puedes escribir las consultas en la línea de comandos o en cualquier cliente gráfico de MySQL, como Workbench.
Es muy importante que se almacenen todas las sentencias que se realicen en los distintos ejercicios. Para ello puedes utilizar cualquier editor de texto plano.
Tanto incluidos en el propio SGBD, como cuando se trata de aplicaciones externas al propio gestor, existen herramientas gráficas que nos ayudan a realizar consultas a una o más tablas de una base de datos de una forma fácil y sencilla, incluso sin necesidad de conocer el lenguaje SQL. Podemos clasificar esas herramientas en:
Estos asistentes son aplicaciones que nos permiten seleccionar las tablas, los campos, el orden de las filas, establecer criterios de selección, grupos y cálculos, etc., siguiendo unos pasos muy sencillos.
Ejemplos de estos asistentes los podemos ver OpenOffice Base y en Microsoft Access, aunque también incorporan este tipo de asistentes bases de datos como Oracle.
Tanto en los propios SGBD como en aplicaciones que se pueden instalar para aumentar las prestaciones y que son externas al SGBD, podemos encontrar herramientas gráficas para diseñar consultas mediante opciones como:
Se trata de herramientas que permiten al usuario elaborar consultas sencillas de forma intuitiva, con el simple manejo de recursos gráficos presentados en una ventana donde se encuentran disponibles todos los elementos que representan las distintas cláusulas que una consulta puede recoger. Aplicaciones como Workbench, phpMyAdmin o Navicat incorporan este tipo de herramientas.
Las cláusulas son las condiciones que modifican nuestras consultas y son utilizadas para definir los datos que desea seleccionar o manipular.
Para ver un ejemplo de cómo crear consultas mediante un asistente te recomendamos que visualices el siguiente vídeo dónde se explica cómo usar el asistente para crear consultas en Access. Pulsa sobre el siguiente enlace para visualizarlo.
Algunas herramientas que permiten trabajar con diferentes SGBD, entre ellos MySQL, son Navicat y SQLMaestro.
Es interesante que accedas a su páginas oficiales y que navegues por ellas para comprobar qué aplicaciones ofrecen para la gestión de servidores de bases de datos. Los enlaces son los siguientes:
En ambos casos puedes descargar la aplicación para MySQL (son versiones de prueba de un determinado número de días). Las puedes instalar en tu ordenador, ejecutarlas, y recorrer las principales opciones. Más adelante las usaremos en algunos ejercicios.
También es interesante que te descargues el manual oficial de esas aplicaciones, en formato pdf (está en inglés).
Aunque hemos citado una serie de herramientas que nos pueden facilitar el diseño de consultas, la herramienta más potente a la hora de establecer criterios para seleccionar la información almacenada en una base de datos es el conocimiento del lenguaje SQL. Todos los SGBD tienen un editor que, con más o menos elementos de ayuda, nos permite introducir nuestras instrucciones y nos muestra dónde se producen los posibles errores.
Veamos un ejemplo con Workbench.
Nos conectamos al servidor MySQL mediante la conexión de Workbench que se ha creado para el usuario root, poniendo la contraseña que dimos en la instalación de MySQL.
Lo normal es que existan diferentes usuarios en el SGBD, cada uno de ellos con ciertos permisos o privilegios sobre las diferentes bases de datos instaladas en el Servidor. Para esos otros usuarios aparecen conexiones en la pantalla inical de Workbench.
De momento, en vuestro caso, tendréis sólo una conexión para el usuario root.
Observa que en la ventana de edición de SQL se escriben las sentencias.
Para ejecutar una sentencia, hacemos los siguiente:
Otras secciones son la Ventana con los resultados de ejecutar las entencias y la ventana en la que el sistema informa del éxito de ejecución o los errores encontrados. En este ejemplo, no hay errroes en la ejecución.
La consulta SELECT * FROM departamento; muesta todos los datos existentes en la tabla departamento.
Observa que se ejecuta sin errores, y se muestran todos los datos de los departamentos.
La consulta SELECT * FROM departamentos;
Observa que se ejecuta con errores y el sistema avisa de ello. El error es, que el nombre de la tabla no es correcto, es departamento sin s al final.
Puedes empezar a practicar sobre la base de datos CAMPEONATO y lanzar una consulta sobre cada una de sus tablas. Para ello vas a usar el cliente gráfico Workbench, de manera que debes tener desplegada (instalada) la base de datos campeonato en el servidor MySQL y después, utilizando la ventana SQL de esta herramienta debes consultar todos los datos de las tablas: concursante, equipo, juego y participa.
En este punto Noiba se dispone a trabajar con el lenguaje de manipulación de datos (LMD), y dentro de él comenzará por las instrucciones que le van a permitir hacer consultas a los datos contenidos en Talleres Faber.
Conociendo esas instrucciones, con consultas fáciles de escribir, podrá saber cosas tan importantes como:
En la unidad anterior clasificamos las sentencias del lenguaje SQL en 4 tipos ¿recuerdas?
| Lenguaje SQL | Sentencias |
|---|---|
| LDD (Lenguaje de Definición de Datos) |
Incluye sentencias para gestionar las. estructuras |
| LMD (Lenguaje de Manipulación de Datos) |
Incluye sentencias para gestionar los datos. |
| LCD (Lenguaje de Control de Datos) |
Incluye sentencias para gestionar la seguridad y los permisos. |
|
LTC (Lenguaje de Control de Transacciones) |
Incluye sentencias para gestionar transacciones |
Pues bien, ahora vamos a tratar con el LMD o DML que es una parte del lenguaje SQL que se encarga de la gestión de los datos almacenados. El LMD tiene instrucciones para ayudarnos a:
Tanto en el LDD, como en el LMD existen sentencias que nos permiten Modificar o Borrar. La diferencia está en que cuando tratamos con el Lenguaje de definición de datos, las instrucciones de modificación y/o borrado afectan a la estructura de la base de datos: tablas, columnas, índices, etc.; es decir, a los objetos que la componen.
Cuando utilizamos instrucciones correspondientes al Lenguaje de manipulación de datos, los cambios que hagamos afectarán a los datos contenidos en la base de datos: las filas de las tablas.
De hecho, los nombres de las sentencias que se usan para crear, modificar y borrar elementos en ambos sublenguajes son diferentes.
Como hemos visto, las herramientas gráficas nos ofrecen una gran ayuda a la hora de enviar consultas a nuestra base de datos. Pero sin duda para tener mayor control sobre cualquier SGBD, y en concreto sobre las consultas a los datos que almacena, Juan recomienda a Noiba y Vindio que lo más seguro es conocer las instrucciones de SQL que integran el LMD o DML.
Para realizar consultas se utiliza la sentencia SELECT. Siguiendo el criterio de Juan, aprenderemos a utilizar las opciones más importantes de SELECT, desde consultas sencillas a una sola tabla hasta consultas complejas combinando datos de varias tablas.
¿Cómo podemos seleccionar los datos que nos interesen dentro de una base de datos? Para recuperar o seleccionar los datos, de una o varias tablas puedes valerte del lenguaje SQL, para ello utilizarás la sentencia SELECT, que consta, como veremos de muchas opciones para poder construir consultas todo lo complejas que puedas imaginar. Veremos en esta unidad las opciones más importantes de la sentencia SELECT.
SELECT es la sentencia que tiene mayores variaciones y opciones sintácticas en todos los SGBD del mercado y también la más compleja y potente de todas las instrucciones SQL.
Utilizaremos esta sentencia para consultar los datos de una base de datos. En la sentencia SELECT el usuario especifica lo que quiere obtener, no cómo, ni dónde.
Como hemos dicho presenta muchas opciones. Las más comunes son:
SELECT
[ALL | DISTINCT | DISTINCTROW ]
{Expresión | Columna1, ... | * }
FROM TablasReferenciadas
[WHERE Condiciones]
[GROUP BY {NombreColumna | Expresión | Posición} …]
[HAVING Condiciones]
[ORDER BY { NombreColumna | Expresión | Posición } [ASC | DESC] , ...]
[LIMIT { [desplazamiento,] contador | contador OFFSET desplazamiento} ]
Antes de empezar a analizar la función de cada una de las cláusulas u opciones de esta sentencia veremos algunas consideraciones generales:
FROM: Según nos indica el formato: <span class=" destacado_inline">SELECT {Expresión | Columna1, ... | * }</span>
Te mostramos algunos Ejemplos.
Ejemplo. Una consulta mostrando todos los datos de los juegos de la base de datos CAMPEONATO. Es una consulta sobre la tabla juego mostrando todas sus columnas.
SELECT * FROM juego;
La redactamos la consulta en la ventana SQL de Workbench. Previamente hay que poner en uso o activar la base de datos campeonato.
El encabezado de las columnas que aparece en las consultas, es el nombre de la columna o expresión correspondiente. Si éste resulta demasiado largo o es el resultado de un cálculo, se puede cambiar usando un alias de columna. Es posible asignar un alias a cualquiera de las expresiones SELECT.
Para ello, se escribe tras el nombre de columna la cláusula <b>AS</b><span> </span>seguida del nuevo nombre que va a aparecer en el encabezado entre comillas, aunque esta palabra AS es opcional.
El alias puede usarse dentro de toda la consulta en cualquier referencia a la columna correspondiente, por ejemplo, dentro de las cláusulas WHERE, HAVING o GROUP BY que veremos a continuación.
Ejemplo. Listado del código, nombre y equipo de los concursantes. Poniendo un alias a las columnas código del concursante y del quipo.
SELECT cdconcur as 'concursante', nombre, cdequipo "equipo"
FROM concursante;
Se indica un alias para cada una de las columnas cdconcur y cdequipo, que son 'concursante' y "equipo" respectivamente. Observa que es opcional poner delante del alias la palabra reservada AS, y además se admite la comilla doble y la comilla simple en MySQL.
Una consulta en SQL puede incluir columnas cuyos valores se obtienen haciendo cálculos a partir de los datos almacenados en las columnas de las tablas. Cuando queremos mostrar el resultado de la columna calculada dentro de SELECT es conveniente utilizar un alias de columna para evitar que se incluya como cabecera la propia función u operación realizada.
Ejemplo 1. Una consulta mostrando el resultado de una cálculo y el resultado de utilizar ciertas funciones del SGBD MySQL, y poniendo un alias a algunos ítems para clarificar o hacer más legible el encabezado del resultado de la consulta.
SELECT 7*4 "Cálculo", USER(), VERSION(),CURDATE() "Fecha Actual", ROUND(10/3,2);
Observa como se sustituye en el encabezado de la consulta el ítem correspondiente por el alias que se ha indicado para esa columna.
Ejemplo 2. Listado de todos los concursantes, con su código, nombre y días de antigüedad (días transcurridos desde su inscripción hasta la fecha actual)
SELECT cdconcur, nombre, datediff(curdate(), fecha_inscri) AS "Antigüedad en días" FROM concursante;
Observa que para obtener los días de antigüedad se ha utilizado la función curdate() que devuelve la fecha actual del sistema y la función datediff() que obtiene la diferencia en días, entre la primera y segunda fecha que le pasamos a la función.
También es válido, y además necesario cuando se seleccionan varias columnas con el mismo nombre en diferentes tablas, especificar el nombre de la columna separado con un punto del nombre de la tabla, de la siguiente forma:
NombreTabla.NombreColumna
Ejemplo. Una consulta que muestre el nombre de cada juego y el nombre de su equipo.
En este caso tenemos una consulta a dos tablas, juego y equipo, y en ambas tablas existe una columna denominada nombre, por lo que para que MySQL puede diferenciarlas se deben calificar, poniendo delante, por ejemplo, el nombre de la tabla de dónde proceden.
SELECT juego.nombre, equipo.nombre FROM juego JOIN equipo ON juego.cdequipo=equipo.cdequipo;
<b>NombreBaseDeDatos.NombreTabla</b>
Ejemplo. Estando en uso otra base de datos diferente a campeonato, se podría lanzar la consulta:
SELECT * FROM campeonato.juego;
De forma general es una combinación de columnas, funciones y operadores que obtiene un resultado.
Se refiere a una expresión o columna incluida en la SELECT.
Las cláusulas ALL y DISTINCT son opcionales.
Veremos su uso en un apartado posterior.
Contesta si es verdadera o falsa la siguiente afirmación:
Falso
Debe respetarse el orden de las cláusulas definido en la sintaxis.Como hemos dicho, la sentencia SELECT admite muchas cláusulas y además éstas presentan diferencias en función del SGBD elegido. A lo largo de esta unidad iremos viendo las más utilizadas y que, en muchos casos, son comunes a un gran número de gestores. Para conocer todas las opciones que admite la sentencia SELECT en MySQL pincha en el siguiente enlace:
Como hemos visto, el formato básico de esta sentencia incluye como mínimo la palabra SELECT y la cláusula FROM. Empezaremos por describir su sintaxis y seguiremos con el resto de las cláusulas que más se utilizan.
<b>SELECT</b>
A continuación de SELECT se especifican las columnas que se desea mostrar. Podemos referenciarlas:
Pero ¿de dónde se extraen esos datos? Justo eso lo indicamos tras el <strong>FROM</strong>.
<b>FROM</b>
Indica la tabla o las tablas que se van a consultar, escribiendo sus nombres separados por comas si se trata de más de una tabla.
Ejemplo: Mostrar el código, nombre y fecha de inscripción de todos los concursantes.
SELECT cdconcur, nombre, fecha_inscri FROM concursante;
Ejemplo: usando Alias de columna.
SELECT cdconcur AS "Código de concursante", nombre, fecha_insri "Fecha de Inscripción" FROM concursante;
Al igual que existen Alias de columna, se pueden indicar alias para la tablas. En este caso el alias de tabla suele estar formado por una o dos letras (La inicial o iniciales de comienzo de la tabla) y no es necesario poner AS ni ponerlo entre comillas.
Un alias se puede utilizar también para asociar un nuevo nombre a una tabla. Se trata de un nombre, generalmente más corto, que se utiliza sobre todo cuando consultamos varias tablas y hay nombres de columnas que coinciden.
Ejemplo. Listar el nombre de cada concursante y el nombre de su equipo.
SELECT c.nombre "Concursante", e.nombre "Equipo" FROM concursante c, equipo e WHERE……… ;
(Hemos asignado el alias c a la tabla concursante y el alias e a la tabla equipo por eso los nombres de las columnas van precedidos del alias c ó e seguido de punto y el nombre de la columna. Además se han puesto alias de columna.
Indica si la siguiente afirmación es verdadera o falsa
Verdadero
Las consultas que hemos realizado hasta ahora muestran todas las filas de la tabla o tablas implicadas.
Pero, ¿Cómo indicamos o ponemos un filtro de selección de manera que solamente se listen las filas que cumplan cierta condición? Eso lo hacemos utilizando la cláusula WHERE.
<span class=" destacado_inline">[WHERE Condiciones]</span>
<b>WHERE</b>
Permite obtener los datos de las filas que cumplen con la condición expresada. Tras <b>WHERE</b> se escribe una expresión de tipo relacional o de comparación que usará alguno de los operadores relacionales y lógicos que veremos después.
El formato de la condición es: expresión operador expresión
Te mostramos algunos ejemplos.
Ejemplo 1. Mostrar el nombre, fecha de inscripción y cuota e los concursantes con cuota de inscripción superior a 70 euros.
SELECT nombre, cuota_inscri, fecha_inscri FROM concursante WHERE cuota_inscri>70;
Que redactada y ejecutada desde Workbench daría el siguiente resultado:
Ejemplo 2. Mostrar el nombre, megusta y dificultad de los juegos cuya dificultad sea 'media' o 'baja'.
En este caso la condición del WHERE es una condición compuesta que usa el operador lógico OR y operadores realacionales de igualdad =
SELECT nombre, megusta, dificultad FROM juego WHERE dificultad="media" OR dificultad="baja";
Un alias, es otra forma de llamar a una tabla o a una columna, y se utiliza para simplificar las sentencias SQL cuando los nombre de tablas o columnas son largos o complicados.
Que redactada y ejecutada desde Workbench daría el siguiente resultado:
Indica si la siguiente afirmación es verdadera o falsa.
Falso
Justo las funciones de agregado o resumen no se pueden incluir en la condición asociada a la cláusula WHERE.
En las consultas del apartado anterior hemos obtenido una lista de nombres de juegos, su dificultad y los megusta que tienen. Nos puede interesar que aparezcan ordenados de más amenos megusta, por ejemplo, o por orden alfabético del nombre del juego. De este modo, si necesitáramos localizar un registro concreto la búsqueda sería más rápida. ¿Cómo lo haremos? Para ello usaremos la cláusula ORDER BY.
ORDER BY se utiliza para especificar el criterio de ordenación de la respuesta a nuestra consulta.
El formato a seguir con ORDER BY es el siguiente:
<span class=" destacado_inline"><strong>[ORDER BY { NombreColumna | Expresión | Posición } [ASC | DESC] ...]</strong> </span><br />
Ejemplo. Ordenando por una columna. El listado con el nombre del juego, su megusta y dificultad, para dificultad 'media' o 'baja', y ordenado de más a menos megusta sería el siguiente: (habría que añadir al final ORDER BY megusta DESC)
SELECT nombre, megusta, dificultad FROM juego WHERE dificultad="media" OR dificultad="baja" ORDER BY megusta DESC;
Ejemplo: Ordenando por dos columnas. En la consulta anterior podemos incluir el código del equipo y ordenar primero por los megusta de forma descendente (de más a menos) y después, en caso de empate, ascendentemente por el código de equipo.
Sería: (Ordenamos por megusta DESC y en caso de empate por cdequipo ASC:)
SELECT nombre, megusta, dificultad, cdequipo FROM juego WHERE dificultad="media" OR dificultad="baja" ORDER BY megusta DESC, cdequipo;
Ejemplo. Ordenando por la posición del campo en la SELECT.
La consulta anterior la podemos expresar de forma equivalente utilizando la posición que ocupa la columna en la SELECT y sería:
SELECT nombre, megusta, dificultad, cdequipo FROM juego WHERE dificultad="media" OR dificultad="baja" ORDER BY 2 DESC, 4;
Observa que el campo megusta ocupa la posición 2 en la SELECT y cdequipo ocupa la posición 4.
Redacta las siguientes consultas sobre la base de datos campeonato:
Ya has visto cómo hacer consultas sencillas sobre una base de datos. A continuación, verás otras cláusulas que permiten eliminar repeticiones y limitar el número de filas a mostrar.
En el formato de SELECT podemos ver:
<span class=" destacado_inline">SELECT [ALL | DISTINCT | DISTINCTROW ] {Expresión | Columna1, ... | * }</span>
La cláusula ALL.
<b>ALL</b>
Permite que se puedan presentar todas las filas afectadas por el resto de condiciones de la consulta aunque algunas filas estén repetidas. Es la opción por defecto.
Ejemplo. Listar el código de los concursantes que participan en juegos.
SELECT ALL cdconcur FROM participa;
(Muestra un listado de los códigos de los concursantes que participan en juegos. Si el concursante participa en más de un juego, su código aparecerá repetido, tal y como puedes ver en la siguiente imagen).
La cláusula DISTINCT.
DISTINCT y DISTINCTROW
Cuando seleccionamos algunas columnas de una o varias tablas pueden mostrarse valores de filas repetidos, como hemos visto en el ejemplo anterior. Pero puede que esas repeticiones, a veces, no aporten información, sino que distorsionen el resultado que andamos buscando, por lo que sería más legible e intuitivo eliminarlas.
Esta cláusula, DSITINCT y DSITINCTROW permite que se puedan presentar todas las filas afectadas por el resto de condiciones de la consulta pero las repetidas aparecen sólo una vez.
Ejemplo. Listar el código de los concursantes que participan en juegos. Sólo nos interesa saber quienes participan en juegos, no en cuantos juegos.
SELECT DISTINCT cdconcur FROM participa;
(Muestra un listado de los códigos de los concursantes que participan en juegos. Si el concursante participa en más de un juego, con DISTINCT evitaremos que su código aparezca repetido).
En la base de datos Campeonato:
Contesta si esta afirmación es verdadera o falsa.
Verdadero
Cierto. En un mismo juego pueden participar más de un concursante y obteniendo más de 10 puntos.
Verdadero
Cierto. Un mismo concursante puede haber iniciado su participación en varios juegos después de esa fecha.
¿Qué hacemos si solamente nos interesa listar un número concreto de filas? Por ejemplo limitar el resultado de una consulta a 3, 10 o 15 filas, por ejemplo.
Para eso usaremos la cláusula LIMIT.
Siempre será la última cláusula a incluir en una SELECT. Su formato es el siguiente:
<span class=" destacado_inline">[LIMIT { [desplazamiento,] contador | contador OFFSET desplazamiento} ]</span>
LIMIT
Permite limitar el número de filas devueltas. Se suele utilizar para no sobrecargar demasiado al servidor o a la aplicación que va a recibir los resultados de la consulta.
LIMIT puede admitir uno o dos parámetros:
Ejemplos.
SELECT * FROM concursante LIMIT 5; -- Devuelve las 5 primeras filas. SELECT * FROM concursante LIMIT 0,5; -- Devuelve las 5 primeras filas. (Se desplaza 0 filas, y devuelve las 5 primeras filas)
SELECT * FROM concursante LIMIT 5,10; -- Devuelve a partir de fila 5, las 10 siguientes
En la base de datos campeonato:
Y si quisiera, por ejemplo, obtener el total de juegos por dificultad. ¿Cómo podría hacerlo? Para ello hay que hacer uso de funciones especiales de agrupamiento y de la cláusula GROUP BY.
Piensa lo que harías manualmente para obtener ese resultado. Seguro que estás pensando en contar en la tabla juego, para cada dificultad diferente, el total de filas que aparecen en esa tabla.
¿Cómo crees que se podría realizar en SQL? Pues de forma algo similar, utilizando la cláusula que permite agrupar registros por valores que se repiten de forma vertical (en columnas), de las filas de la tabla.
Si observas la siguiente imagen de la tabla juego, con diferente color, se resaltan los grupos que harías: un grupo para dificultad alta, otro para dificultad baja y otro para dificultad media, y contarías cuantas veces aparece cada uno. Pues eso es lo que hace la cláusula GROUP BY.
El formato a seguir con GROUP BY es el siguiente:
<span class=" destacado_inline">[GROUP BY {NombreColumna | Expresión | Posición} …]</span>
GROUP BY
Es posible agrupar las filas que devuelve una consulta según los valores de una columna, usando la cláusula GROUP BY. Aunque en algunos casos podríamos hacer esto mismo usando la opción DISTINCT, esta cláusula es más potente y presenta las siguientes diferencias:
Estas funciones también se pueden usar sin la cláusula GROUP BY siempre que en la consulta no se seleccionen otras columnas. Estas consultas se denominan consultas de resumen y las veremos en esta unidad.
Esta cláusula GROUP BY, combinada con las funciones de agregado anteriores, permite hacer cálculos sobre una serie de filas agrupadas. A estas consultas las denominaremos consultas agrupadas y se verán en un apartado posterior.
Ejemplo. Para obtener el total de juegos por dificultad, sería:
SELECT dificultad, count(*) 'Total Juegos' FROM juego GROUP BY dificultad;
El formato a seguir con HAVING es el siguiente:
<span class=" destacado_inline">[HAVING Condiciones]</span>
HAVING
Permite hacer selecciones o filtros de grupos, en situaciones en las que no es posible usar WHERE. La cláusula WHERE no se puede aplicar a columnas calculadas mediante las funciones de agrupamiento que hemos mencionado en el apartado anterior. Tanto la cláusula GROUP BY como HAVING se tratarán más adelante en las consultas agrupadas.
Pero a título de ejemplo, veamos el siguiente.
Ejemplo. Para obtener el total de juegos por dificultad, pero listando solo si hay más de 3 juegos, sería:
SELECT dificultad, count(*) 'Total Juegos' FROM juego GROUP BY dificultad HAVING count(*) >3;
Indica si la siguiente afirmación sobre HAVING es verdadera o falsa.
Verdadero
Filtramos grupos con HAVING en situaciones en las que no es posible usar WHERE. La cláusula WHERE<span> </span>no se puede aplicar a columnas calculadas mediante las funciones de agrupamiento
Aunque ya hemos visto en la unidad anterior algunos operadores que pueden intervenir en una sentencia SQL, dado que en la mayor parte de los casos se incluyen en sentencias de tipo SELECT, vamos a ampliar en este apartado los tipos de operadores.
Con el lenguaje SQL podemos utilizar muchos operadores diferentes para cada tipo de columna. Veremos los operadores de que dispone MySQL, pero la mayoría de ellos son compatibles con otros SGBD. Pero ¿qué es un operador?
Los operadores son símbolos que permiten realizar operaciones matemáticas, concatenar cadenas o hacer comparaciones, entre otras funciones
Los operadores se utilizan para construir expresiones que se usan en cláusulas WHERE, ORDER BY y HAVING y además se pueden emplear directamente en las sentencias.
Es la representación perceptible de una idea, con rasgos asociados por una convención socialmente aceptada.
Con frecuencia utilizaremos la sentencia SELECT acompañada de expresiones muy extensas y resultará difícil saber que parte de dicha expresión se evaluará primero, por ello es conveniente conocer el orden de precedencia en MySQL.
Para consultar el orden de prioridad de los operadores disponibles en MySQL pincha en el siguiente enlace:
Si quieres connocer todos los operadores que se pueden usar en MySQL consulta el siguinte enlace:
Sabemos que los operadores son símbolos que permiten realizar distintos tipos de operaciones. Vamos a verlos.
En MySQL podemos crear variables de sesión y usarlas posteriormente en expresiones. Podemos crear variables de dos formas:
SET @hoy= CURRENT_DATE(); SELECT @hoy;
(Veremos la fecha actual)
SET @X:=10; SELECT @X;
(Veremos el valor almacenado 10)
Una variable sin asignar será de tipo cadena y su valor será NULL.(ausencia de valor)
Los operadores aritméticos se aplican a valores numéricos, ya sean enteros o en coma flotante. El resultado siempre es un valor numérico, entero o en coma flotante.
MySQL dispone de los operadores aritméticos habituales: suma, resta, multiplicación, división, potencia, etc.
| Operador | Significado |
|---|---|
| + | Se utiliza para sumar dos números y, como operador unario, para simbolizar signo positivo de un número. |
| - | Se utiliza para hallar la diferencia entre dos números y, como operador unario, para simbolizar signo negativo de un número. |
| * | Se utiliza para multiplicar dos números. |
| / | Se utiliza para dividir dos números. |
| ^ | Se utiliza para elevar un número a la potencia del exponente (número ^ exponente). |
| \ | Se utiliza para dividir dos números y el resultado cociente en forma de entero (división entera) entero. |
| % o <b>mod</b> | Dividen dos números y devuelven el resto entero de la división. |
| - | Se obtiene un valor de signo contrario. |
El orden de precedencia, entre los operadores artiméticos, es el siguiente:
Ejemplo:
Por tanto, los paréntesis permitirán forzar el orden de evaluación de una expresión.
También denominada, variable de usuario, se escribe con el prefijo de una @ y mantiene el valor asignado durante la sesión en curso. No hay que especificar el tipo de dato.
Los puedes conocer con otros nombres como relacionales, nos permitirán comparar expresiones, que pueden ser valores concretos de campos, variables, etc.
Los operadores de comparación son símbolos que se usan como su nombre indica para comparar dos valores. Estos operadores devuelven los valores lógicos de verdadero o falso. (1 ó 0). A esta expresiones cuyo resultado de evaluación es verdadero o falso se les denomina expresiones lógicas
Estos operadores son habituales en cualquier lenguaje de programación, pero algunos lenguajes como SQL añade algunos muy útiles que se usan frecuentemente.
| Operador | Significado |
|---|---|
| < = | Menor o igual. |
| < | Menor. |
| > | Mayor. |
| > = | Mayor o igual |
| = | Compara dos expresiones y devuelve 1, sin son iguales y 0, si son diferentes. |
| < => | Funciona como =, salvo que si una de las dos expresiones o las dos es nula, el resultado no es NULL. Si se comparan dos expresiones nulas, el resultado es verdadero (1). |
| < > ó != | Si las expresiones comparadas son diferentes, el resultado es verdadero, y si son iguales, el resultado es falso. |
Estos operadores tienen todos ellos la misma prioridad.
Los operadores relacionales pueden usarse para comparar cadenas.
Habrá ocasiones en las que tengas que evaluar más de una expresión y necesites verificar que se cumple una única condición, otras veces comprobar si se cumple una u otra o ninguna de ellas. Para poder hacer esto utilizaremos los operadores lógicos.
Los operadores lógicos se usan para crear expresiones lógicas complejas.
Solo existen dos valores posibles para los resultados: verdadero y falso, pero MySQL añade un tercer valor: desconocido para poder trabajar con valores NULL.
| 1 | <b>TRUE</b> |
| 0 | <b>FALSE</b> |
| desconocido | <b>NULL</b> |
| Operador | Función |
|---|---|
| <b>AND</b> ó <b>&& </b> | Devuelve el valor TRUE cuando las dos condiciones son verdaderas y FALSE si alguna de ellas es falsa. |
| <b>OR</b> ó || | Devuelve el valor TRUE si cualquiera de las dos condiciones es verdadera y FALSE cuando las dos condiciones son falsas |
| <b>NOT</b> ó <b>!</b> | Devuelve lo opuesto a la condición que sigue a NOT. Si el operador es NULL devuelve NULL. |
| <b>XOR</b> | Devuelve NULL si cualquiera de los operadores es NULL. Cuando uno de los operadores es verdadero, devuelve TRUE y si ambos son verdaderos o falsos devuelve FALSE. |
Todos estos operadores tienen menor precedencia en las expresiones que los operadores aritméticos. Entre ellos, el orden de precedencia es el siguiente:
Al igual que todos los operadores binarios que veremos, estos operadores se pueden asociar, es decir, se pueden crear expresiones como:
Te mostramos a continuación algunos ejemplos prácticos de todo esto.
Ejemplo 1.
Listado de los concursantes cuya cuota de inscripción sea mayor que 20€ y menor o igual a 100€ , y su equipo es el '04'
SELECT * FROM concursante WHERE cuota_inscri>20 AND cuota_inscri<=100 AND cdequipo='04';
Se define como operación binaria aquella operación matemática, que necesita el operador y dos operandos para que se calcule un valor.
Ejemplo 2.
Listado de los concursantes cuya cuota de inscripción es mayor que 20€ y menor o igual a 100€, y el equipo puede ser el '04' o el '02'.
SELECT * FROM concursante WHERE cuota_inscri>20 AND cuota_inscri<=100 AND (cdequipo='04' OR cdequipo='02');
Observa el uso del paréntesis para forzar el orden de evaluación de los operadores AND y OR. Primero se evalúa el paréntesis comprobando que el equipo sea el '02' o el '04' y después se enlaza con AND, para que de forma simultánea se cumpla que la cuota está en el rango especificado.
En la base de datos Campeonato, consultar los datos de los concursantes inscritos antes del 2020, con cuota menor a 100 euros y cuyo equipo sea el '02' o '03':
En la base de datos campeonato obtén las siguientes consultas:
En MySQL disponemos de varios operadores adicionales que vemos a continuación.
LIKE y NOT LIKE
La sintaxis de LIKE es:
<span class=" destacado_inline">WHERE Expresión [NOT] LIKE patrón</span>
En SQL de MySQL tenemos dos caracteres especiales que pueden aparecer en cualquier posición del patrón:
| Comodín | Significado |
|---|---|
| % | Representa a cualquier cadena de 0 o más caracteres. |
| _ | Representa a un carácter cualquiera. |
Te mostramos algunos ejemplos.
Ejemplo 1. Listar el nombre y código de equipo de los concursantes cuyo nombre comience por la letra M.
SELECT nombre, cdequipo FROM concursante WHERE nombre LIKE “M%”;
Ejemplo 2. Listar el nombre y código de equipo de los concursantes cuyo nombre contiene la palabra 'rojo'.
SELECT nombre, cdequipo FROM concursante WHERE nombre LIKE '%rojo%';
Ejemplo 3. Listar el nombre y código de equipo de los concursantes cuyo nombre contiene como segunda letra una E.
SELECT nombre, cdequipo FROM concursante WHERE nombre LIKE'_E%';
Ejemplo 4.- Listado de concursantes cuyo nombre no contiene la palabra 'Verde', basta con usar NOT LIKE patrón.
SELECT nombre, cdequipo FROM concursante WHERE nombre NOT LIKE'%Verde%';
<b>BETWEEN y NOT BETWEEN</b>
Sirve para comprobar si una expresión está comprendida o no en un determinado rango de valores. La sintaxis es:
WHERE Expresión [NOT] BETWEEN ValorInicial AND ValorFinal.
Ejemplo 1. Obtener un listado con el nombre y las cuotas de concursantes, para aquellos cuya cuota está entre 50 y 100 euros, incluido el 50 y 100.
SELECT nombre, cuota_inscri FROM concursante WHERE cuota_inscri BETWEEN 50 AND 100;
También podríamos haber escrito:
SELECT nombre, cuota_inscri FROM concursante WHERE cuota_inscri >= 50 AND cuota_inscri<=100;
Ejemplo 2. Listado de concursantes que se inscribieron entre los años 2019 y 2021.
SELECT * FROM concursante WHERE fecha_inscri BETWEEN '2019-01-01' AND '2021-12-31';
Ejemplo 3. Y si queremos justo lo contrario, concursantes inscritos en años fuera del periodo 2019 - 2021, basta con negar el criterio anterior.
SELECT * FROM concursante WHERE fecha_inscri NOT BETWEEN '2019-01-01' AND '2021-12-31';
y si además, supiéramos de la existencia de la función YEAR(), que devuelve el año de la fecha que se le pasa como parámetro, podrías resolver estas consultas de la forma:
SELECT * FROM concursante WHERE YEAR(fecha_inscri) BETWEEN 2019 AND 2021; -- SELECT * FROM concursante WHERE YEAR(fecha_inscri) NOT BETWEEN 2019 AND 2021;
Las funciones que nos proporciona MySQL las veremos en una apartado posterior. Ahora es solamente para ilustrar cómo podemos ir integrándolas en las consultas.
Observa la diferencia entre las dos soluciones del Ejemplo 1:
IN, NOT IN
El operador IN devuelve 1 (verdadero) si el valor de la expresión es igual a alguno de los valores de la lista y falso en caso contrario. El operador<b> NOT IN</b> devuelve 1 (verdadero) si el valor de la expresión no está en la lista.
La sintaxis es:
WHERE Expresión IN [NOT IN] (Valor1, Valor2, ……. )
Expresion = valor1 OR Expresion=valor2 OR Expresion=valor3 ...Ejemplo 1. Listado de los concursantes cuyo equipo sea el '01', '02' o el '04'.
SELECT *
FROM concursante
WHERE cdequipo IN('01', '02','04');
También podríamos haber escrito:
SELECT * FROM concursante WHERE cdequipo = '01' OR cdequipo ='02' OR cdequipo ='04';
Ejemplo 2. Listado de los concursantes cuyo equipo no es el '01', '02' ni el '04'.
SELECT *
FROM concursante
WHERE cdequipo NOT IN('01', '02','04');
Basta con negar con NOT la condición anterior.
En la base de datos campeonato, realiza las siguientes consultas:
Las siguientes consultas ¿son equivalentes?
Falso
Solamente son equivalentes las consultas 2.- y 3.-
En este punto Noiba plantea revisar el tratamiento que se hace en los SGBD de los valores nulos. Ella sabe que no es lo mismo que un campo contenga el valor nulo o que contenga un cero.
Conviene que nos detengamos con ella en este punto porque de no hacerlo así no podríamos diferenciar cuando el valor de un dato en una columna no ha sido introducido y por eso lo desconocemos, de cuando ese dato existe y es un cero o un espacio en blanco.
¿Cómo indicamos que no hay valor en un determinado campo de una tabla? Lo haremos con un valor nulo.
Datos y nulos
Un dato es una unidad de información con sentido que se almacena en un campo. Dependiendo del contenido de la información almacenada, los datos pertenecen a diferentes tipos: cadenas de caracteres, fechas, o números, etc.
Un valor nulo es un valor que no es asignable a ningún tipo de datos y que significa que no se ha definido ningún valor inicial para ese dato, es decir que el valor de ese dato es desconocido.
Un cero o un espacio en blanco es un valor que se ha asignado a un campo, por tanto el campo tiene un contenido: el cero o el espacio en blanco.
Se dice que el contenido de una columna para un elemento es NULL si está completamente vacía, no se cargó en su momento ningún valor.
Este valor es compatible con todos los tipos de datos y significa ausencia de valor.
IS NULL, IS NOT NULL
Para comprobar si en una columna hay un valor nulo se utiliza la expresión:
<span class=" destacado_inline">NombreColumna IS NULL</span>
Ejemplo.
La siguiente consulta muestra los datos de los concursantes que no pertenecen a ningún equipo.
SELECT * FROM concursante WHERE cdequipo IS NULL;
Por el contrario, para comprobar si en una columna hay algún valor, se emplea la expresión:
<span class=" destacado_inline">NombreColumna IS NOT NULL</span>
Ejemplo.
La siguiente consulta muestra los datos de los concursantes que si pertenecen a algún equipo.
SELECT * FROM concursante WHERE cdequipo IS NOT NULL;
Los operadores aritméticos con valores nulos devuelven un valor nulo.
Noiba y Vindio han reunido información sobre los distintos tipos de operadores que pueden intervenir en las consultas SQL. A menudo estos operadores intervienen en expresiones construidas también con funciones, por eso considera importante consultar la documentación relativa a las funciones que podrían ser de utilidad. Dado que MySQL dispone de multitud de funciones no considera necesario conocerlas todas. Siguiendo sus pasos nos conformaremos con agruparlas por tipos y ver las más comunes. Para el resto de funciones incluiremos el enlace correspondiente.
¿Has pensado en todas las operaciones que puedes realizar con los datos que guardas en una base de datos? Seguro que son muchísimas. Pues bien, en casi todos los Sistemas Gestores de Base de Datos existen funciones ya creadas que facilitan la creación de consultas más complejas. Dichas funciones varían según el SGBD, veremos aquí las que utiliza MySQL.
Las funciones son realmente operaciones que se realizan sobre los datos y que realizan un determinado cálculo. Para ello necesitan unos datos de entrada llamados parámetros o argumentos y en función de éstos, se realizará el cálculo de la función que se esté utilizando. Normalmente los parámetros se especifican entre paréntesis.
Las funciones se usan dentro de expresiones y actúan sobre los valores de las columnas de las tablas, con variables o con constantes. Se utilizan en cláusulas SELECT, WHERE y ORDER BY.
Las funciones pueden producir dos tipos de resultados:
Podemos clasificar las funciones en varios tipos:
Funciones aritméticas:
Funciones de cadena de caracteres:
Funciones de manejo de fechas y horas:
Funciones de comparación:
Se trata de funciones que comparan los valores de cada una de las columnas en el interior de una fila para obtener: el menor o el mayor valor de ellos, así como comprobar si el valor de una columna es nulo.
En el siguiente documento te presentamos un resumen de las funciones de cada tipo que se utilizan con más frecuencia en MySQL y algunos ejemplos de aplicación:
Verdadero
MONTHNAME() devuelve el nombre del mes de la fecha pasada y YEAR() devuelve el año de la fecha pasada como parámetro.
Como hemos dicho, existen muchas funciones que pueden aplicarse a las columnas de una tabla. En algunas herramientas gráficas se encuentran accesibles todas las funciones disponibles agrupadas por categorías.
Para consultar la documentación relativa a todas las funciones ya implementadas en MySQL puedes acceder a lsiguiente enlace:
Noiba está reuniendo información sobre los distintos tipos de consulta que se pueden realizar sobre las tablas de la base de datos Talleres Faber. En este momento veremos cómo obtener resúmenes de los datos aplicando sobre las columnas una serie de funciones de grupos. Estas funciones van a permitir calcular, por ejemplo, el precio medio de los recambios, el número de vehículos que visitan el taller en un mes, el tiempo máximo que dura una reparación, etc.
Está claro que se trata de cuestiones que pueden tener mucho interés para el taller mecánico. Veamos cómo obtener esos datos
La sentencia SELECT nos va a permitir obtener resúmenes de los datos de modo vertical. Para ello consta de una serie de cláusulas específicas (GROUP BY, HAVING) y tenemos también unas funciones llamadas de agrupamiento o de agregado que son las que nos dirán qué cálculos queremos realizar sobre los datos (sobre la columna).
Hasta ahora las consultas que hemos visto daban como resultado un subconjunto de filas de la tabla de la que extraíamos la información. Sin embargo, este tipo de consultas que vamos a ver no corresponde con ningún valor de la tabla sino un total calculado sobre los datos de la tabla. Esto hará que las consultas de resumen tengan limitaciones que iremos viendo.
Las funciones que podemos utilizar se llaman de agrupamiento (de agregado). Éstas toman un grupo de datos (una columna) y producen un único dato que resume el grupo. Por ejemplo, la función SUM() acepta una columna de datos numéricos y devuelve la suma de estos.
Las funciones de grupos de valores ignoran los valores nulos a la hora de realizar los cálculos.
Estas funciones se muestran en la siguiente tabla:
| FUNCIONES DE COLUMNA | Descripción |
|---|---|
| COUNT(Expresión o Columna) | Cuenta el número de valores no nulos de la columna que aparece como argumento. Si ponemos * cuenta las filas que tengan valor no nulo. |
| SUM(Expresión o Columna) | Calcula la suma de los valores numéricos indicados en el argumento. |
| MIN(Expresión o Columna) | Obtiene el valor mínimo del argumento indicado. |
| MAX(Expresión o Columna) | Obtiene el valor máximo del argumento indicado. |
| AVG(Expresión o Columna) | Obtiene la media aritmética del argumento indicado. No considera los valores nulos. |
El argumento de estas funciones suele ser un nombre de columna.
El simple hecho de utilizar una función de agregado en una consulta la convierte en consulta de resumen.
Todas las funciones tiene una sintaxis similar a la siguiente:
FUNCION ([DISTINCT | ALL] expresión)
Debemos tener en cuenta que:
Analiza las siguientes consultas:
SELECT COUNT(DISTINCT cdequipo) 'Equipos' FROM concursante;<br />SELECT DISTINCT COUNT(cdequipo) 'Equipos' FROM concursante;
¿De qué forma interviene la cláusula DISTINCT en ambas?
Realiza las siguientes consultas en la base de datos campeonato:
Realiza las siguientes consultas en la base de datos campeonato:
Cuando hemos recorrido con Noiba y Vindio las cláusulas de la sentencia SELECT, hemos visto que podíamos utilizar GROUP BYpara agrupar filas yHAVINGpara establecer condiciones en las filas agrupadas. Combinando estas cláusulas con las funciones de grupo del apartado anterior, Juan les dice a Noiba y Vindio que podrán encontrar soluciones a cuestiones que hasta ahora no podían resolver y que pueden ser útiles.
Por ejemplo, saber cuántos vehículos de cada marca visitan el taller podría resultar interesante a la hora de especializar a los mecánicos en determinados motores.
En el apartado anterior hemos usado funciones de grupo para calcular totales, obteniendo un único dato resumen. Las consultas agrupadas nos permitirán realizar cálculos de grupo sobre filas que tienen un valor coincidente en una o varias columnas, y obtener subtotales.
Como ejemplo, observa las siguientes imágenes:
Imagina que en la base de datos de campeonato queremos saber, por ejemplo, ¿cuántos concursantes hay de cada equipo? Hasta ahora lo que podíamos hacer era mostrar las filas de la tabla concursante, ordenadas por cdequipoy contar visualmente cuántas filas había por cada equipo, de la siguiente forma:
Ejemplo 1. Listado de los equipos de los concursantes ordenado por código de equipo.
SELECT cdequipo FROM concursante ORDER BY cdequipo;
¿Y si la tabla tuviera miles de filas? No podríamos hacerlo así. Es el momento de recurrir a la cláusula GROUP BY.
Seguidamente se obtiene un listado con dos columnas: El código de equipo y el número de concursantes de ese equipo. La consulta devolverá una fila por cada cdequipo diferente, con el código del equipo y el número de concursantes de ese equipo. El listado estará ordenado por cdequipo.
SELECT cdequipo AS 'equipo', count(*) AS 'concursantes' FROM concursante GROUP BY cdequipo ORDER BY cdequipo;
En el listado obtenido observarás que aparece una fila con valor NULL para cdequipo y con 3 concursantes.
Eso significa en nuestra base de datos que hay 3 concursantes sin equipo asignado. Si nos interesara eliminar del listado a los concursantes sin equipo ¿Cómo lo hacemos? Incluyendo un filtro WHERE de la tabla, para que no se considere el valor NULL de la columna cdequipo. La consulta sería:
SELECT cdequipo AS 'equipo', count(*) AS 'concursantes' FROM concursante WHERE cdequipo IS NOT NULL GROUP BY cdequipo ORDER BY cdequipo;
Ejemplo 2.
Imagina que nos interesa filtrar ese listado obtenido anteriormente con GORUP BY de manera que sólo aparezca el código de los equipos con 4 o más concursantes. ¿Cómo lo hacemos? En este caso no se usa WHERE, lo que se utiliza es la cláusula HAVING que es la que permite filtrar los grupos obtenidos con GROUP BY , quedando por lo tanto la consulta de la siguiente forma:
SELECT cdequipo AS 'equipo', count(*) AS 'concursantes' FROM concursante WHERE cdequipo IS NOT NULL GROUP BY cdequipo HAVING count(*)>=4 ORDER BY cdequipo;
Tanto GROUP BY como HAVING se usan en consultas de resumen. La sintaxis de estas consultas es:
SELECT NombreColumna,…, Función,…
FROM NombreTabla
[WHERE Condiciones…..]
GROUP BY NombreColumaDeGrupo
[HAVING Condiciones]
[ORDER BY Criterio]
En la cláusula GROUP BY se colocan las columnas por las que vamos a agrupar. En la cláusula HAVING se especifica la condición que han de cumplir los grupos para que se realice la consulta.
Debes tener en cuenta el orden en el que se ejecutan las cláusulas indicadas anteriormente:
Las columnas que aparecen en el SELECT y que no aparezcan en la cláusula GROUP BY deben tener una función de agrupamiento. Si esto no se hace así producirá un error en el SQL estándar. Otra opción es poner en la claúsula GROUP BY las mismas columnas que aparecen en SELECT.
En el caso de MySQL, se acepta incluir en la SELECT otras columnas que no aparezcan en el GROUP BY, como por ejemplo:
Una consulta que liste para equipo, su código, nombre, comunidad y total de concursantes del equipo.
SELECT equipo.cdequipo, equipo.nombre, count(*) 'concursantes' FROM concursante INNER JOIN equipo ON equipo.cdequipo=concursante.cdequipo GROUP BY concursante.cdequipo;
En la base de datos campeonato, obtener la media de puntos acumulados por cada concursante que participa en juegos, mostrando únicamente el código de concursante cuya media no sea inferior a 40 puntos.
En la base de datos campeonato, realiza las siguientes consultas:
Indica si las siguientes consultas son equivalentes para listar el total de juegos por equipo, siempre que el equipo tenga más de 2 juegos.
Falso
Sólo es correcta la consulta 1.-
La consulta 2.- es incorrecta y dará error, pues la cláusula WHERE no admite el uso de funciones de agregado.
Hasta ahora nos hemos dejado guiar por Noiba y Vindio para aprender a realizar consultas sencillas que manejaban una sola tabla. Pero Juan, les idnica que ha llegado el momento de realizar consultas más complejas para obtener datos de varias tablas. Está claro que en el diseño de Talleres Faber intervienen múltiples tablas y que en el trabajo diario con la base de datos estas consultas van a ser frecuentes. Tendremos que seguir los pasos de Alejandra para aprender a combinar las tablas y hacer consultas que muestren los resultados buscados.
En las consultas realizadas hasta ahora sólo hemos utilizado una tabla que se indicaba a la derecha de la cláusula FROM, pero hay veces que una consulta necesita acceder a columnas de varias tablas (recuerda que en el modelo relacional los datos los tenemos distribuidos en diferentes tablas). Por ejemplo, obtener ciertos datos de los juegos (tabla juego) junto a datos de sus equipos (tabla equipo), habrá que incluir en la consulta esas dos tablas.
Ejemplo 1.
Imagina que, en la base de datos campeonato, queremos un listado en el que se muestren los nombres de todos los juegos, su dificultad y el nombre del equipo organizador. Tendremos que consultar las tablas juego y equipo. ¿Y cómo las consultamos? Es importante que al consultarlas las combinemos de forma correcta, esto es, por las columnas que permiten relacionar esas tablas, que normalmente será la columna que es clave ajena en una tabla y la clave primaria de la otra tabla. En las siguientes imágenes te lo explicamos.
La columna cdequipo es clave ajena o foránea en la tabla juego, y permite relacionar esta tabla con la tabla equipo por esa columna.
La columna cdequipo es clave primaria en la tabla equipo, y permite relacionar esta tabla con la tabla juego por esa columna, ya que en la tabla juego existe una clave ajena o foránea que la referencia.
En la siguiente imagen puedes ver el resultado de combinar las tablas equipo y juego y listar para cada juego, su nombre, dificultad, código de equipo y nombre de equipo organizador.
SELECT j.nombre 'juego', j.dificultad, e.cdequipo, e.nombre 'equipo' FROM juego j, equipo e WHERE j.cdequipo=e.cdequipo;
Observa que:
Observa que si al hacer la consulta multitabla omitimos el filtro de combinación de las tablas, (... WHERE j.cdequipo=e.cdequipo ) lo que se obtiene es lo que se llama 'el producto cartesiano' de esas tablas, esto es, cada fila de una tabla combinada con todas las filas de la segunda tabla.
SELECT j.nombre 'juego', j.dificultad, e.cdequipo, e.nombre 'equipo' FROM juego j, equipo e;
¿Qué ocurre si combinamos dos o más tablas sin ninguna restricción? El resultado será un producto cartesiano.
El producto cartesiano entre dos tablas da como resultado todas las combinaciones de todas las filas de esas dos tablas.
Se indica poniendo en la cláusula FROM las tablas que queremos componer separadas por comas. Y puedes obtener el producto cartesiano de las tablas que quieras.
Como lo que se obtiene son todas las posibles combinaciones de filas, debes tener especial cuidado con las tablas que combinas. Si tienes dos tablas de 20 filas cada una, el resultado tendrá 20x20 filas, a medida que aumentemos el número de filas que contienen las tablas, mayor será el resultado final, con lo cual se puede considerar que nos encontraremos con una operación costosa.
Esta operación no es de las más utilizadas ya que toma una fila de una tabla y la asocia con todas y cada una de las filas de la otra tabla, independientemente de que tengan relación o no. Lo más normal es que queramos seleccionar los registros o filas según algún criterio.
Necesitaremos discriminar de alguna forma para que únicamente aparezcan filas de una tabla que estén relacionadas con la otra tabla. A esto se le llama asociar tablas (JOIN).
Para hacer una composición interna se parte de un producto cartesiano y se eliminan aquellas filas que no cumplen la condición de composición.
Lo importante en las composiciones o combinaciones internas es emparejar las columnas que han de tener valores iguales (las que permiten relacionar las tablas).
Cuando combinamos varias tablas tenemos que tener en cuenta:
NombreTabla.NombreColumna o bien aliasTabla.NombreColumna
Ejemplo 2. En la base de datos campeonato, oun listado con el nombres de los concursantes, su cuota y el nombre y comunidad de su equipo.
Como en las tablas concursante y equipo hay columnas con el mismo nombre, se deben denominar anteponiendo el nombre de la tabla o el alias de la tabla.
SELECT c.nombre 'concursante', c.cuota_inscri, e.nombre 'equipo', e.comunidad FROM concursante c, equipo e WHERE c.cdequipo=e.cdequipo;
Ejemplo 3. Listar el nombre y cuota de los concursantes de sexo femenino (mujeres), junto con el código del juego en el que participan y los puntos conseguidos.
SELECT nombre, cuota_inscri, sexo, cdjuego 'juego', puntos FROM concursante, participa WHERE concursante.cdconcur=participa.cdconcur and sexo ='M';
En este caso no es necesario indicar en la SELECT el nombre a alias de la tabla delante del nombre de la columna, pues tienen denominaciones diferentes, pero observa que queda bastante más legible y es un buena práctica calificar cada columna indicando la tabla de la que proviene.
SELECT c.nombre, c.cuota_inscri, c.sexo, p.cdjuego 'juego', p.puntos FROM concursante c, participa p WHERE c.cdconcur=p.cdconcur and c.sexo ='M';
En matemáticas, el producto cartesiano de dos conjuntos es el producto directo de dos conjuntos. Por ejemplo, el producto cartesiano de dos conjuntos A y B, denotado como A x B, es el conjunto de todos los pares ordenados en los que el primer componente pertenece al conjunto A y el segundo a B.
En matemáticas, el producto cartesiano de dos conjuntos es el producto directo de dos conjuntos. Por ejemplo, el producto cartesiano de dos conjuntos A y B, denotado como A x B, es el conjunto de todos los pares ordenados en los que el primer componente pertenece al conjunto A y el segundo a B.
Cuando realizamos consultas a varias tablas y no especificamos las columnas por las que se relacionan, el resultado de la consulta es el producto cartesiano, tal y como hemos explicado. Este resultado casi siempre será un error. En muy pocos casos nos interesa mezclar filas de una tabla con filas de otra, sin ningún criterio para establecer esa combinación.
Ejemplo: si combinamos en una consulta juegos con equipos sin hacer coincidir el cdequipo en ambas tablas, obtendremos un listado que mezcla cada juego con todos los equipos de la tabla. Desde un punto de vista lógico esta consulta no tendría ningún sentido.
Las columnas que aparecen en la cláusula WHERE se denominan columnas de emparejamiento, composición o combinación ya que son las que permiten combinar las filas de las dos tablas. Éstas no tienen por qué estar incluidas en la lista de selección. Combinamos tablas que estén relacionadas entres sí y además, una de las columnas de combinación será clave principal en su tabla, y en otra tabla será clave ajena. Cuando combinamos columnas debemos especificar de la siguiente forma: NombreTabla1.Camporelacionado1 = NombreTabla2.Camporelacionado2
En la base de datos campeonato, realiza las siguientes consultas:
Cuando en el apartado 7 hemos aprendido a hacer consultas a los datos contenidos en varias tablas combinando las filas, nos hemos dejado por el camino un tipo de consultas que pueden ser también de utilidad en un taller como talleres Faber, porque permiten mostrar, no sólo los empleados y las reparaciones en las que han intervenido, sino que se podrá conocer también los empleados que no hayan intervenido en ninguna reparación. Lo vemos con Noiba.
Las combinaciones de tablas que hemos visto hasta ahora en consultas multitabla son “Composiciones o combinaciones internas”. En éstas se combina información procedente de dos o más tablas, formando filas relacionadas según la condición de búsqueda establecida con WHERE que generalmente es la clave principal de una tabla y la clave ajena relacionada en la otra tabla.
En la versión SQL de 1999 o SQL99 se especifica una nueva sintaxis para consultar varias tablas que MySQL incorpora, así que también la veremos. La razón de esta nueva sintaxis era separar las condiciones de combinación de tablas respecto a las condiciones o filtros de selección de registros. Además, esta nueva sintaxis permitirá realizar dos tipos de combinación de tablas:
No centramos en este apartado en la combinación interna.
Estas composiciones se denominan internas porque en el resultado no aparece ninguna fila de una tabla que no tenga correspondencia con las filas de la tabla con la que se combina.
SELECT … FROM NombreTabla1 , NombreTabla2 WHERE condición de relación..
SELECT … FROM NombreTabla1 INNER JOIN NombreTabla2 ON condición de relación..
En la base de datos campeonato, la consulta que muestra para cada juego su nombre, dificultad, código y nombre de su equipo organizador se puede formular de dos formas:
SELECT j.nombre 'juego', j.dificultad, e.cdequipo, e.nombre 'equipo' FROM juego j, equipo e WHERE j.cdequipo=e.cdequipo;
SELECT j.nombre 'juego', j.dificultad, e.cdequipo, e.nombre 'equipo' FROM juego j INNER JOIN equipo e ON j.cdequipo=e.cdequipo;
Una buena práctica es utilizar JOIN en vez de solo WHERE, pues así separamos las condiciones de combinación de las tablas con el filtro de selección. Observa el siguiente ejemplo.
En la consulta anterior, supongamos que el listado solo se desea para los juegos cuyo equipo organizador es de Andalucía o Murcia. Las consultas serían:
SELECT j.nombre 'juego', j.dificultad, e.cdequipo, e.nombre 'equipo'
FROM juego j, equipo e
WHERE j.cdequipo=e.cdequipo AND e.comunidad IN ('Andalucia', 'Murica');
SELECT j.nombre 'juego', j.dificultad, e.cdequipo, e.nombre 'equipo'
FROM juego j
INNER JOIN equipo e ON j.cdequipo=e.cdequipo
WHERE e.comunidad IN('Andalucia', 'Murica');
Otras sintaxis de combinación interna, igualmente equivalentes, son:
SELECT … FROM NombreTabla1 JOIN NombreTabla2 ON condición de relación..
SELECT … FROM NombreTabla1 JOIN NombreTabla2 WHERE condición de relación..
SELECT ….FROM NombreTabla1 INNER JOIN NombreTabla2 USING(ColumnaRelacionada)..
Las columnas que aparecen en la cláusula WHERE, ON o USING, se denominan columnas de emparejamiento, combinación o composición ya que son las que permiten combinar las filas de las dos tablas. Éstas no tienen por qué estar incluidas en la lista de selección. Combinamos tablas que estén relacionadas entres sí y además, una de las columnas de emparejamiento será clave principal en su tabla y clave ajena en la otra tabla. Si las dos columnas de combinación tieen el mismo nombre, se puede usar USING(nombre_columna) o bien si se usa WHERE u ON, habrá que calificar la columna con el alias o nombre de la tabla correspondiente.
Seguimos viendo otros ejemplos sobre la base de datos campeonato.
En la salida de la siguiente consulta sólo aparecen los datos de los concursantes que participan en juegos, y los juegos en los que participan. Los concursantes que no participan en juegos no aparecen. Para los concursantes que participan en varios juegos su código y nombre se repiten.
SELECT concursante.cdconcur, concursante.nombre, participa.cdjuego, juego.nombre FROM concursante INNER JOIN participa ON concursante.cdconcur = participa.cdconcur INNER JOIN juego ON juego.cdjuego=participa.cdjuego;
De otra forma, con USING sería:
SELECT concursante.cdconcur, concursante.nombre, participa.cdjuego, juego.nombre FROM concursante INNER JOIN participa USING(cdconcur) INNER JOIN juego USING(cdjuego);
Esta consulta combina 3 tablas para obtener el importe (unidades*precio) de los recambios sustituidos en cada reparación.
SELECT REPARACIONES.IdReparacion, sum(Unidades * PrecioReferencia) AS 'Importe recambios' FROM (REPARACIONES INNER JOIN Incluyen ON REPARACIONES.IdReparacion=Incluyen.IdReparacion) INNER JOIN RECAMBIOS ON Incluyen.IdRecambio=RECAMBIOS.IdRecambio GROUP BY IdReparacion;
Compara las siguientes alternativas para definir combinaciones internas:
¿Por qué podemos considerar que la sintaxis empleada en la opción b es más restrictiva que la de la opción a?
En la base de datos campeonato, realiza las siguientes consultas:
Revisando la información que es necesario obtener en el taller mecánico, Vindio se ha dado cuenta que hay casos en los que es necesario mostrar en los listados filas de una tabla que no están relacionadas con la tabla con la que se combina. Por ejemplo, si se desea un listado con todos los clientes y las facturas enviadas, y en el listado se desea que aparezccan también los clientes a los que aún no se le han enviado facturas. ¿Cómo obtener esos datos? Noiba, le recuerda que para esos casos existen las combinaciones externas.
¿Has pensado que puede que te interese seleccionar algunas filas de una tabla aunque éstas no tengan correspondencia con las filas de la otra tabla? Esto puede ser necesario.
Por ejemplo, en la base de datos campeonato, hay concursantes que no tienen equipo, van por libre. Si se deseara un listado con los nombres de todos los concursantes y el nombre de su equipo, con una combinación interna no lo podríamos obtener, pues sólo se combinan las filas en las que hay coincidencia en las columnas de combinación. ¿Cómo se puede obtener? En este caso hay que usar una combianción externa.
Una combinación externa es una variedad de composición de tablas que permite seleccionar algunas filas de una tabla aunque éstas no tengan correspondencia con las filas de la otra tabla con la que se combina. Cuando no existe correspondencia en la segunda tabla se combina con NULL.
La combinación externa puede expresarse de dos formas:
La sintaxis equivalente en ambos casos para LEFT JOIN:
SELECT ….FROM NombreTabla1 LEFT JOIN NombreTabla2 ON condición de relación..
SELECT ….FROM NombreTabla1 LEFT JOIN NombreTabla2 USING(ColumnaRelacionada)…
SELECT ….FROM NombreTabla1 LEFT OUTER JOIN NombreTabla2 ON condición de relación..
La sintaxis equivalente en ambos casos para RIGHT JOIN:
SELECT ….FROM NombreTabla1 RIGHT JOIN NombreTabla2 ON condición de relación..
SELECT ….FROM NombreTabla1 RIGHT JOIN NombreTabla2 USING(ColumnaRelacionada)…
SELECT ….FROM NombreTabla1 RIGHT OUTER JOIN NombreTabla2 ON condición de relación..
Vemos algunos ejemplos con la base de datos campeonato.
Ejemplo 1. Listado con el código y nombre de cada concursante y el código y nombre de su equipo. En el listado deben aparecer todos los concursantes, aunque no tengan equipo. Ordenar el listado por nombre de concursante. Con LEFT JOIN.
SELECT c.cdconcur, c.nombre 'concursante', e.cdequipo, e.nombre 'equipo' FROM concursante c LEFT JOIN equipo e ON c.cdequipo=e.cdequipo ORDER BY c.nombre;
Para los concursantes que no tengan equipo, aparecerá el valor NULL en las columnas e.cdequipo y e.cdnombre.
Ejemplo 2. Listado con el código y nombre de cada concursante y el código y nombre de su equipo. En el listado deben aparecer todos los concursantes, aunque no tengan equipo. Ordenar el listado por nombre de concursante. Con RIGHT JOIN.
SELECT c.cdconcur, c.nombre 'concursante', e.cdequipo, e.nombre 'equipo' FROM equipo e RIGHT JOIN concursante c ON c.cdequipo=e.cdequipo ORDER BY c.nombre;
Para los concursantes que no tengan equipo, aparecerá el valor NULL en las columnas e.cdequipo y e.cdnombre.
Ejemplo 3. Listado con el código y nombre de cada concursante y el código y nombre de su equipo. En el listado deben aparecer todos los concursantes, aunque no tengan equipo. Ordenar el listado por nombre de concursante. Con LEFT JOIN y usando la función IFNULL() para personalizar los valores nulos.
SELECT c.cdconcur, c.nombre 'concursante', IFNULL(e.cdequipo,'***'),IFNULL(e.nombre, 'SIN EQUIPO') 'equipo' FROM concursante c LEFT JOIN equipo e ON c.cdequipo=e.cdequipo ORDER BY c.nombre;
Para los concursantes que no tengan equipo, aparecerá el valor *** en la columna e.cdequipo y SIN EQUIPO en la columna e.cdnombre.
Vemos otros ejemplos incluyendo otras cláusulas de la SELECT
Ejemplo 4. Listado con el código y nombre de cada concursante con el código y nombre de los juegos en los que participan. Si el concursante no participa en juegos debe salir también en el listado.
SELECT c.cdconcur, c.nombre, p.cdjuego FROM concursante c LEFT JOIN participa p ON c.cdconcur=p.cdconcur;
(En este caso aunque tengamos algún concursante que no participe en juegos se mostrará su código y nombre. Y en la columna de la tabla participa p.cdjuego, aparecerá NULL).
Ejemplo 5. El mismo ejemplo anterior pero formulado con con RIGHT JOIN.
SELECT c.cdconcur, c.nombre, p.cdjuego FROM participa p RIGHT JOIN concursante c ON c.cdconcur=p.cdconcur;
Observa que al formular la misma consulta del Ejemplo4 con RIGHT JOIN la tabla que aparece a la derecha de RIGHT JOIN es concursante, que es la tabla de la que interesa que se listen todas las filas, aunque no se puedan combinar con ninguna fila de la participa.
Con la base de datos campeonato, obtener un listado de los juegos registrados en nuestra base de datos, su código y nombre, y el total de concursantes que participan en cada uno de ellos, y los puntos acumulados.
Ordena el listado de manos a más puntos acumulados y si hay juegos en los que no se participa, debe aparecer *** como puntos acumulados.
En la base de datos campeonato, realiza las siguientes consultas:
Indica si las siguientes consultas son equivalentes.
Verdadero
Observa que si se usa LEFT JOIN, se listan todas las filas de la tabla a la izquierda o delante de LEFT JOIN, se puedan o no realcionar con filas de la otra tabla.
Y si se usa RIGHT JOIN, se listan todas las filas de la tabla a la derecha o detrás de RIGHT JOIN, se puedan o no relacionar con filas de la otra tabla.
Por lo que ambas sentencias son equivalentes.
Para más información sobre las combinaciones de tablas en MySQL consulta el siguiente enlace.
En este apartado vamos a aprender a diseñar un tipo de consultas que puede ser de gran utilidad en nuestro proyecto. Alejandra se encuentra en muchos casos con tablas que, teniendo la misma estructura, contienen información que se refiere a distintos periodos de tiempo. Por ejemplo las facturas de los clientes almacenadas en distinta tabla cada año (facturas_2010, facturas_2011). Vindio y Noiba nos van a mostrar cómo podríamos unir la información que contienen dos o más tablas en una consulta, para saber, por ejemplo, la facturación acumulada desde que Talleres Faber inició su actividad.
Seguro que cuando empieces a trabajar con bases de datos llegará un momento en que dispongas de varias tablas con los mismos datos guardados para distintos registros y quieras unirla en una única tabla. ¿Esto se puede hacer? Es una operación muy común junto a otras. Al fin y al cabo, una consulta da como resultado un conjunto de filas y con conjuntos podemos hacer tres tipos de operaciones muy comunes como son: unión, intersección y diferencia.
Además, existen otros tipos de composiciones SQL99 que vamos a ver a continuación.
Como has visto anteriormente, SQL incluye en esta versión de 1999 mejoras de la sintaxis a la hora de crear composiciones en consultas multitabla. Hemos visto las composiciones internas (INNER JOIN) y externas (LEFT/RIGHT OUTER JOIN), pero existen otros tipos de composiciones.
La sintaxis de estas composiciones es la siguiente:
SELECT tabla1.columna1, tabla1.columna2, …, tabla2.columna1, tabla2.columna2, …
FROM tabla1
[CROSS JOIN tabla2] |
[NATURAL JOIN tabla2] |
[JOIN tabla2 USING (columna)] |
[JOIN tabla2 ON (tabla1.columna=tabla2.columna)] |
[LEFT | RIGTH | FULL OUTER JOIN tabla2 ON (tabla1.columna=tabla2.columna)];
<span class=" resaltado_inline">CROSS JOIN</span>
CROSS JOIN: realiza un producto cartesiano de las filas de ambas tablas por lo que sería el equivalente a usar la cláusula WHERE sin indicar las columnas de empearejamiento de las tablas.
Ejemplo.
La siguiente consulta realiza el producto cartesiano entre las tablas juego y equipo, de manera que cada juego lo combina con todos los equipos de la tabla equipo.
SELECT juego.cdjuego, juego.nombre, juego.cdequipo, equipo.nombre FROM juego CROSS JOIN equipo;
Y es equivalente a esta otra consulta.
SELECT juego.cdjuego, juego.nombre, juego.cdequipo, equipo.nombre FROM juego, equipo;
<span class=" resaltado_inline">NATURAL JOIN</span>
NATURAL JOIN: detecta automáticamente las columnas de emparejamiento, basándose en el nombre de la columna que coincide en ambas tablas. Por lo tanto, se requerirá que las columnas de emparejamiento tengan el mismo nombre en cada tabla. Además, esta característica funcionará incluso si no están definidas las claves primarias o ajenas.
Ejemplo.
La siguiente consulta expresada con NATURAL JOIN no mostraría nada, pues combina las tablas juego y equipo por las columnas que tienen igual denominación, que son cdequipo y nombre, y está claro que el nombre de un equipo y el nombre de un juego no tiene nada que ver, y no hay coincidencia de valores en esas columnas de ambas tablas.
SELECT juego.cdjuego, juego.nombre, juego.cdequipo, equipo.nombre FROM juego NATURAL JOIN equipo;
<span class=" resaltado_inline">JOIN USING</span>
JOIN USING: esta cláusula permite establecer relaciones entre tablas indicando qué columna o columnas comunes se quieren utilizar para ello. Por lo tanto, las columnas de emparejamiento deben tener el mismo nombre en cada tabla.
Ejemplo.
La siguiente consulta expresada con JOIN USING combina las tablas juego y equipo por la columna que tiene igual denominación en ambas tablas cdequipo y que permite relacionarlas, por lo que mostrará el código y nombre de cada juego, junto al código y nombre de su equipo.
SELECT juego.cdjuego, juego.nombre, juego.cdequipo, equipo.nombre FROM juego JOIN equipo USING(cdequipo);
<span class=" resaltado_inline">JOIN ON</span>
JOIN ON: se utiliza para componer tablas en las que los nombres de las columnas de emparejamiento no coinciden en ambas tablas o se necesita establecer asociaciones más complicadas. Si las columnas de emparejamiento se denominan igual en las tablas, será necesario calificar con el nombre de la tabla o con su alias a cada columna de emparejamiento.
Ejemplo.
La siguiente consulta expresada con JOIN ON combina las tablas juego y equipo por la columna que tiene igual denominación en ambas tablas cdequipo y que permite relacionarlas, por lo que mostrará el código y nombre de cada juego, junto al código y nombre de su equipo.
SELECT juego.cdjuego, juego.nombre, juego.cdequipo, equipo.nombre FROM juego JOIN equipo ON juego.cdequipo=equipo.cdequipo;
<span class=" resaltado_inline">LEFT OUTER JOIN</span>
LEFT OUTER JOIN: es una composición externa izquierda, todas las filas de la tabla de la izquierda se devuelven, aunque no haya ninguna columna correspondiente en las tablas combinadas.
Ejemplo.
La siguiente consulta expresada con LEFT OUTER JOIN combina las tablas concursante y equipo por la columna que tiene igual denominación en ambas tablas cdequipo y que permite relacionarlas, y al ser un LEFT JOIN, mostrará el código y nombre de todos los concursantes (tabla a la izquierda del JOIN) tengan o no equipo, por lo que para los que no tienen equipo las columnas de la tabla equipo estarán a NULL.
SELECT concursante.cdconcur, concursante.nombre, equipo.cdequipo, equipo.nombre FROM concursante LEFT OUTER JOIN equipo ON concursante.cdequipo=equipo.cdequipo;
<span class=" resaltado_inline">RIGTH OUTER JOIN</span>
RIGTH OUTER JOIN: es una composición externa derecha, todas las filas de la tabla de la derecha se devuelven, aunque no haya ninguna columna correspondiente en las tablas combinadas.
Ejemplo.
La siguiente consulta expresada con RIGHT OUTER JOIN combina las tablas concursante y equipo por la columna que tiene igual denominación en ambas tablas cdequipo y que permite relacionarlas, y al ser un RIGHT JOIN, mostrará el código y nombre de todos los equipos (tabla a la derecha del JOIN) tengan o no concursantes, por lo que para los que no tienen concursantes las columnas de la tabla concursante estarán a NULL.
SELECT equipo.cdequipo, equipo.nombre, concursante.cdequipo, concursante.nombre FROM concursante RIGHT OUTER JOIN equipo ON concursante.cdequipo=equipo.cdequipo;
<span class=" resaltado_inline">FULL OUTER JOIN</span>
FULL OUTER JOIN: es una composición externa en la que se devolverán todas las filas de las columnas no relacionados de ambas tablas. (No implementado en MySQL)
El FULL OUTER JOIN, se puede emular en MySQL mediante la unión (UNION) de las dos consultas anteriores.
Ejemplo.
La siguiente consulta muestra todos los concursantes tengan o no equipo, y todos los equipos, tengan o no concursantes.
SELECT concursante.cdconcur, concursante.nombre, equipo.cdequipo, equipo.nombre FROM concursante LEFT OUTER JOIN equipo ON concursante.cdequipo=equipo.cdequipo UNION SELECT concursante.cdconcur, concursante.nombre, equipo.cdequipo, equipo.nombre FROM concursante RIGHT OUTER JOIN equipo ON concursante.cdequipo=equipo.cdequipo;
Utilizando la base de datos campeonato, realiza las siguientes consultas:
Verdadero
En ambos casos se está combinando con un JOIN INTERNO las tablas juego y equipo por la columna que permite relacionarlas, la columna cdequipo.
Las consultas de unión, intersección y diferencia, son consultas que utilizan al menos dos SELECT cuyos resultados se pueden combinar para formar una sola consulta. Se basan en los operadores matemáticos de conjuntos: (unión, intersección y diferencia.
Vamos a ver en qué consisten estos tipos de consultas:
Para estas tres operaciones es muy importante que:
Estas operaciones se pueden combinar anidadas, pero es conveniente utilizar paréntesis para indicar qué operación quieres que se haga primero.
Las vemos a continuación en más detalle y con ejemplos de cada una de ellas.
<span class=" resaltado_inline">UNION</span>
Esta operación se realiza sobre:
El resultado es una consulta (tabla de la consulta) incluyendo las filas de la primera consulta y a continuación las filas de las siguientes consultas.
La sintaxis para realizar una UNION es:
SELECT…..FROM…..WHERE….. UNION [ALL | DISTINCT] SELECT……. FROM…….WHERE….
Si no se especifica ALL o DISTINCT por defecto se usa DISTINCT, por lo que se eliminan las filas repetidas que pudiera dar el resultado final de la unión de consultas.
Las condiciones en las que se establece una consulta de unión son:
Ejemplo.
Si en un centro educativo tenemos una base de datos centro con una tabla, de nombre FPgeneral, para el alumnado que cursa Ciclos Formativos de Informática por la mañana en Régimen General y otra tabla de similar estructura y columnas, de nombre FPsemipresencial, para el alumnado que cursas esos mismo Ciclos Formativos por la tarde en régimen Semipresencial, podríamos obtener una consulta que nos listara el nombre y apellidos, e email de todo el alumnado que cursa el ciclo formativo de código DAM o DAW ordenado por código de ciclo formativo, apellidos y nombre.
SELECT apellidos, nombre, email, codciclo "Código Ciclo"
FROM FPgeneral
WHERE codciclo in('DAM', 'DAW')
UNION
SELECT apellidos, nombre, email, codciclo
FROM FPsemipresenical
WHERE codciclo in('DAM', 'DAW')
ORDER BY codciclo, apellidos, nombre;
Supongamos que en la base de datos campeonato tenemos dos tablas con datos de equipos. La tabla equipo con los datos de los equipos dados de alta hasta el año 2020 y otra tabla con la misma estructura que equipo denominada equipos<b>_20 </b>con los datos de equipos dados de alta a partir de 2020.
Vamos a realizar una consulta de unión entre los equipos de ambas tablas correspondientes a los años comprendidos entre 2018 y 2023. Ordenar el listado por año de fundación.
NOTA.
Para poder probarla, debes crear la tabla equipos_20 con filas en común en ambas tablas.
<span class=" resaltado_inline">INTERSECT</span>
Como te hemos indicado, esta sentencia permite obtener un listado de las filas que tienen en común las consultas de las que se hace intersección, siempre que cumplan los requisitos indicados anteriormente: mismo número de columnas compatibles en tipo de dato y en el mismo orden.
Ejemplo.
En una escuela de música que imparten clases de chelo y piano, se almacenan los datos del alumnado en dos tablas diferentes: alum_chelo, y alum_piano, respectivamente. Las tablas tienen la misma estructura, columnas y tipo de dato de columna. Si la escuela de música necesita obtener el nombre y el email de los alumnos que cursan chelo y piano , para enviarles cierta información, podría obtener un listado de todos ellos mediante la siguiente consulta:
SELECT nombre, email FROM alum_chelo INTERSECT SELECT nombre, email FROM alum_piano;
De momento, hasta la versión 8.0.30, MySQL no soporta INTERSEC, pero se puede emular el funcionamiento de esta sentencia mediante:
Ejemplo.
En la base de datos campeonato, si tenemos dos tablas con datos de equipos: equipo y equipos_20 (con los datos indicados en el Ejercicio resuelto UNION), podemos obtener los equipos en común en ambas tablas (la intersección) de la siguiente forma:
SELECT equipo.* FROM equipo INNER JOIN equipos_20 ON equipos_20.cdequipo=equipo.cdequipo;
<span class=" resaltado_inline">MINUS</span>
Como te hemos indicado, esta sentencia devuelve aquellas filas que están en el primer SELECT pero no en el segundo. Y es requisito, que las columnas de las SELECT implicadas sean igual en número, mismo orden y tipos de datos compatibles.
Ejemplo.
Si ahora, en la escuela de música necesitaran obtener un listado, con el nombre y el email, del alumnado que cursa solamente chelo, la consulta a realizar sería la siguiente:
SELECT nombre, email FROM alum_chelo MINUS SELECT nombre,eamil FROM alum_piano;
De momento, hasta la versión 8.0.30, MySQL no soporta MINUS, pero se puede emular el funcionamiento de esta sentencia mediante:
Ejemplo.
Si interesa listar el código, nombre y año de fundación de los equipos que hay en la tabla equipo y que no están en la tabla equipos_20 (la diferencia), la consulta sería la siguiente:
SELECT cdequipo, nombre, anio_funda
FROM equipo
WHERE (cdequipo, nombre, anio_funda) NOT IN
(SELECT cdequipo, nombre, anio_funda FROM equipos_20);
Verdadero
El nombre de las columnas no tiene porqué coincidir. Es necesario que los datos sean compatibles.Siguiendo los pasos de Noiba, parece que ya estamos listos para escribir cualquier tipo de consulta en SQL que nos permita acceder a la información almacenada, pero no es así. En muchas ocasiones para realizar una consulta necesitaremos los datos devueltos por otra consulta. Investigaremos con Alejandra si este tipo de consultas, denominadas subconsultas, están recogidas en el SQL de nuestro SGBD. MySQL ,y cómo se utilizan.
Para entender la necesidad de realizar una subconsulta veremos un ejemplo: supongamos que queremos obtener un listado con los concursantes que cuya cuota es superior a la cuota media.
Con lo que hemos visto hasta ahora necesitaríamos hacer dos consultas:
En primer lugar, haríamos la primera consulta:
SELECT AVG(cuota_inscri) FROM concursante;
Supongamos que el Importe medio obtenido sea 66,32. Ahora haríamos la segunda consulta basada en el resultado anterior:
SELECT * FROM concursante WHERE cuota_inscri >66.32;
Las subconsultas permiten escribir estas dos consultas en una, escribiendo tras la cláusula WHERE otra sentencia SELECT. Así el SELECT principal actúa sobre las filas devueltas por el SELECT anidado.
La sintaxis será:
SELECT NombreColumna,…. FROM NombreTabla,… WHERE Expresión OperadorRelacional (SELECT….)
En nuestro ejemplo sería:
SELECT * FROM concursante WHERE cuota_inscri > (SELECT AVG(cuota_inscri) FROM concursante);
La subconsulta entre paréntesis (subconsulta anidada) se ejecuta primero y el valor extraído se introduce en la consulta más externa.
El tipo de dato de la expresión situada después de WHERE debe coincidir con el tipo de dato devuelto por la subconsulta.
Se trata de subconsultas que devuelven un valor simple. En estas se utilizan los operadores de comparación (<, >, <>, <=, >=, =). Si la subconsulta devuelve más de una fila da ERROR.
Ejemplo 1. Listado con el nombre de los concursantes del mismo equipo que Ismael Rojo.
Sabemos que esta subconsulta, en nuestro modelo de base de datos, sólo puede devolver un valor, pues un concursante solamente puede pertenecer a un equipo.
SELECT cdconcur, nombre FROM concursante WHERE cdequipo = (SELECT cdequipo FROM concursante WHERE nombre LIKE 'Ismael Rojo');
Son subconsultas que devuelven más de una fila o más de un valor. En ese caso utilizaremos
NOT IN .ANY combinados con algún operador relacional. Donde ALL indica todos y ANY indica alguno.Pero ¿Cómo se realiza la comparación con la subconsulta utilizando estos operadores?
Ejemplo 2. Listado de los concursantes que aún no están participando en ningún juego.
SELECT * FROM concursante WHERE cdconcur NOT IN (SELECT cdconcur FROM participa);
Ejemplo 3. Datos de los concursantes que son ídolos de otros concursantes.
SELECT * FROM concursante WHERE cdconcur IN (SELECT cdidolo FROM concursante);
Ejemplo 4. Código, nombre, y cuota de los concursantes con mayor que todos los concursantes del equipo '01'.
SELECT cdconcur, nombre, cuota_inscri FROM concursante WHERE cuota_inscri > ALL (SELECT cuota_inscri FROM concursante WHERE cdequipo='01');
Observa que > ALL indica mayor que todos, y es equivalente a la siguiente subconsulta expresada como mayor que el máximo:
SELECT cdconcur, nombre, cuota_inscri FROM concursante WHERE cuota_inscri > (SELECT MAX(cuota_inscri) FROM concursante WHERE cdequipo='01');
Ejemplo 5. Listado de juegos con valor en megusta, menor que alguno de los juegos del equipo '03'
SELECT * FROM juego WHERE megusta < ANY (SELECT megusta FROM juego WHERE cdequipo ='03');
Observa que < ANY indica menor que alguno, y es equivalente a la siguiente subconsulta expresada como menor que el máximo:
SELECT * FROM juego WHERE megusta < (SELECT MAX(megusta) FROM juego WHERE cdequipo ='03');
Dentro de una consulta se pueden usar varias subconsultas enlazadas con el operador AND. Las subconsultas se pueden usar dentro de otras sentencias como DELETE, INSERT y UPDATE.
Las subconsultas pueden anidarse de forma que una subconsulta aparezca en la cláusula WHERE de otra subconsulta o incluso como ítem de una SELECT.
También pueden aparecer subconsultas tras las cláusulas FROM y HAVING. (A la subconsulta tras FROM se le denomina tabla derivada y debe llevar un alias de tabla)
En la base de datos campeonato, realiza las siguientes consultas:
En la base de datos campeonato
Indica si la siguiente afirmación es verdadera o falsa.
Falso
Una subconsulta puede aparecer también detrás de un FROM, y en ese caso, a la tabla que genera se le denomina tabla derivada y es obligatorio ponerle un alias.
Puedes conusltar otros ejemplos de subconsultas y más posibilidades de uso en el siguiente enlace:
Siguiendo los pasos de Noiba, ahora sí, estamos listos para escribir cualquier tipo de consulta en SQL que nos permita acceder a la información almacenada. Para poner en práctica todo lo aprendido Noiba junto a Vindio se atreven a gestionar algunos proyectos que ha llegado a BK Sistemas Informáticos.
Uno de esos proyectos consiste en gestionar la base de datos para una Web de alquileres online de disfraces, otro trata de gestionar la base de datos de un campeonato de juegos JamToday y otro en la gestión de la base de datos de una Agencia de Viajes y la gestión de las reservas.
En los siguientes apartados vamos a resolver algunos casos prácticos de realización de consultas en las que intervengan las cláusulas de la sentencia SELECT vistas en esta unidad, así como la creación de vistas (VIEW) para facilitar la realización de consultas complejas, reutilizando su código. También verás ejemplos de cómo el uso de índices (INDEX) adecuados, optimiza la realización de determinadas consultas.
El comercio Disfraces BK dispone de una base de datos para gestionar los alquileres de disfraces a sus clientes. La base de datos de nombre disfraces está formada por las tablas DISFRAZ, CATEGORIA, ALQUILER y CLIENTE, y su modelo o esquema relacional es el siguiente:
¿Cómo funciona el alquiler de disfraces?
El comercio Disfraces BK nos solicita que le resolvamos las siguientes consultas y que intentemos optimizar algunas de ellas que se realizan con bastante frecuencia. También le interesa que dejemos almacenada la definición de las consultas más complejas para poder reutilizar ese código.
Lo que nos solicita es lo siguiente:
Para desarrollar y probar las consultas puedes descargar la base de datos disfraces desde aquí (zip - 1,40 KB).
Disponemos de la base de datos de nombre jamtoday para gestionar la participación de estudiantes y profesorado en la creación o gestión de videojuegos educativos en la Asociación BK sin ánimo de lucro. Los estudiantes y profesorado se catalogan como concursantes que pueden o no integrarse en un equipo. Los equipos son los que crean y gestionan los juegos. Por otra parte, cualquier concursante puede votar con cierta puntuación los juegos que le parezcan más interesantes. Además, todos los concursantes pueden aportar de forma periódica un donativo a la Asociación BK.
Sobre esta base de datos nos piden realizar una serie de consultas para obtener cierta información de interés. Antes de redactar las consultas, debemos tener claro las columnas de cada tabla y la forma en la que éstas se relacionan. Por ello, es importante conocer el modelo de la base de datos, tanto su modelo Entidad/Relación, como el modelo Relacional. Estos modelos son los siguientes:
El modelo ENTIDAD/RELACIÓN de la base de datos es el siguiente:
El MODELO RELACIONAL (modelo lógico) de la base de datos es el siguiente:
El modelo de la base de datos obtenido mediante ingeniería inversa y personalizado según el modelo Entidad/Relación que nos dan, es el siguiente:
Sobre la Base de Datos Jamtoday, la Asociación BK nos pide que resolvamos las siguientes consultas que son de su interés:
Para desarrollar y probar las consultas puedes descargar la base de datos <strong>jamtoday</strong> desde aquí (zip - 2,31 KB).
Se proporcionan dos scripts, el primero que debes ejecutar es el que crea la estructura de la base de datos (bd_jamtoday_create.sql) y después el que inyecta o inserta los datos (bd_jamtoday_datos.sql).
Materiales desarrollados inicialmente por el Ministerio de Educación, Cultura y Deporte y actualizados por el profesorado de la Junta de Andalucía bajo licencia Creative Commons BY-NC-SA.

Antes de cualquier uso leer detenidamente el siguente Aviso legal
| Versión: 02.00.00 | Fecha de actualización: 24/05/23 | Autoría: Isabel Cruz Granados |
|---|---|---|
Ubicación: Apartado 1.1 Asistentes y herramientas gráficas de diseño Ubicación: En la Unidad Ubicación: Mapa Ubicación: Tabla de contenidos | ||
| Versión: 01.00.00 | Fecha de actualización: 23/07/20 | |
|---|---|---|
| Versión inicial de los materiales. | ||