DQL (una tabla)
| Tema | Título | Subtema | Versión |
|---|---|---|---|
| 04 | El modelo físco: SQL | PARTE II | v 1.0 |
| 04 | DQL Una tabla |

DQL (Data Query Language)
Introducción
La sentencia SELECT, que se utiliza para expresar consultas SQL, es la más potente y compleja de las sentencias de SQL. Este capítulo discute las consultas SQL más simples: aquellas que recuperen datos de una única tabla de la BD.
La sentencia SELECT consta de 6 cláusulas:
| Clausula | Descripción |
|---|---|
| SELECT | Lista los elementos a recuperar. Pueden ser columnas de la BD o expresiones a partir de las columnas, etc. |
| FROM | Lista las tablas de donde se recuperan los elementos. Las consultas que extraen sus datos de una única tabla se describen en este capítulo. Las de más de 2 tablas las veremos más adelante. |
| WHERE | Especifica las filas a recuperar. Se utilizan una expresión condicional |
| GROUP BY | Agrupa las filas similares y produce una fila de resultados por cada grupo. |
| HAVING | especifica una consulta sumaria. En lugar de producir una fila de resultados por cada fila de datos, una consulta sumaria agrupa todas las filas similares y después produce una fila de resultados por cada grupo. |
| ORDER BY | ordena los resultados de la consulta en base a los datos de una o más columnas. Si se omite, los resultados de la consulta no aparecen ordenados |
La cláusula SELECT
Esta cláusula consta de la palabra SELECT, seguida por la lista de elementos que queremos obtener (separados por comas). Cada elemento de la lista puede ser: un nombre de columna, una constante, una expresión, el símbolo * (se lee all) o funciones internas:
-
a) Nombre de las columnas
SELECT cod, precio FROM artículoscod precio Tomates 2.50 Patatas 1.25 Manzanas 1.90 Cebollas 1.50 Si queremos renombrar las columnas en el resultado de la consulta podemos utilizar
ASy luego el alias que queremos que aparezca:SELECT cod as COD_ART, precio as PRICE_ART FROM artículosCOD_ART PRICE_ART Tomates 2.50 Patatas 1.25 Manzanas 1.90 Cebollas 1.50 -
b) Una constante
Cuando utilizamos constantes, el valor que le demos se reproducirá en todas las filas del resultado de la consulta. Las constantes pueden ser numéricas, de cadena, de fecha y hora o simbólicas.
Constantes numéricas
SELECT código, precio, 21 AS 'IVA' FROM artículoscódigo precio IVA Tomates 2.50 21 Patatas 1.25 21 Manzanas 1.90 21 Cebollas 1.50 21 Van sin comillas. El separador decimal es el punto. Pueden llevar los signos + o -
Ejemplos numéricos: 21, -375, 2000.00, +497500.8778
Constantes de cadena
Van siempre entre comillas simples o dobles. Si queremos poner una cadena que contiene comillas, lo cerraremos entre comillas dobles. Si queremos poner dentro de unas comillas dobles, lo pondremos entre comillas simples.
Ejemplos:
- 'Del “Marenyet”'
- "L'Alcudia"
SELECT código, "del Mareny" AS 'origen', precio FROM artículoscódigo origen precio Tomates del Mareny 2.50 Patatas del Mareny 1.25 Manzanas del Mareny 1.90 Cebollas del Mareny 1.50 -
Constantes de fecha y hora
Entre comillas simples o dobles. Se indica año, mes y día separados por la barra (/), guión (-) o dos puntos (:). No tiene mucho sentido ponerlas en la cláusula SELECT pero sí en la WHERE:
SELECT código, precio, fecha FROM artículos WHERE fecha > '2015/7/8'; -- o bien: “2015-7-8” o '2015:07:08'código precio fecha Tomates 2.50 2015/7/9 Patatas 1.25 2015/9/4 Manzanas 1.90 2015/9/2 Cebollas 1.50 2016/1/9 Investiga: averigua si la fecha se puede poner en otro formato, y la forma de poner las horas. Fechas
- Constantes simbólicas
SQL incluye constantes simbólicas especiales que devuelven valores de datos mantenidos por el propio SGBD. Algunas son: CURRENT_DATE (para la fecha), CURRENT_TIME (para la hora), CURRENT_TIMESTAMP (para fecha y hora). No requieren la cláusula FROM.
SELECT CURRENT_DATE, CURRENT_TIME;CURRENT_DATE CURRENT_TIME 2016-01-25 19:32:34 -
c) Una expresión
Las expresiones se utilizan en el lenguaje SQL para calcular valores derivados de los existentes en la BD (y para realizar búsquedas en la BD). Los operadores matemáticos son los normales: suma ( + ), resta ( – ), multiplicación ( * ) y división ( / ).
SELECT cantidad, precio, precio * 1.21 FROM artículos WHERE cantidad * precio > 1.50;cantidad precio (cantidad * precio) * 1.21 3 3.00 10.89 2 4.00 9.68 3 2.00 7.26 4 5.00 24.20 -
d) El símbolo
*Sirve para mostrar todas las columnas de una tabla.
Uso de
*Se utiliza con mucha frecuencia para obtener de manera rápida todo el contenido de una tabla, no hace falta concocer su estructura ya que actúa como un comodín que representa todas las columnas de la tabla.
SELECT * FROM [nombre_tabla];SELECT * FROM autores;codigo nombre país 1 Umberto Eco Italia 3 Camilo J. Cela España 4 Homero Grecia 5 M. Cervantes España De esta manera rápida podemos ver la estructura de la taba
autoresque son 3 columnas (codigo, nombre y país) y todo el contenido, 4 registros. -
e) Funciones internas
MySQL incluye algunas funciones internas. Por ejemplo:
Sobre fechas:
SELECT fecha_nacimiento, DAY(fecha_nacimiento), MONTH(fecha_nacimiento), YEAR(fecha_nacimiento), DAYNAME(fecha_nacimiento) FROM alumnos WHERE YEAR(fecha_nacimiento) > 1960;fecha_nacimiento DAY(fecha_nacimiento) MONTH(fecha_nacimiento) YEAR(fecha_nacimiento) DAYNAME(fecha_nacimiento) 1970-12-30 30 12 1970 Wednesday 1975-11-03 3 11 1975 Monday 1985-10-18 18 10 1985 Friday Sobre cadenas:
SELECT nombre, CHAR_LENGTH(nombre), CONCAT(ap1, “ “, ap2, “, ”, nombre) as `Nombre_completo`, LOWER(nombre), UPPER(nombre) FROM alumnos;nombre longitud Nombre_completo Minúsculas Mayúsculas Pep 3 Garcia Garcia, Pep pep PEP Jaime 5 Peris Martí, Jaume jaume JAUME Sebastián 8 Pino Garcia, Sebastián sebastián SEBASTIÁN Investiga: mira en Internet otras funciones para trabajar en las fechas, cadenas, etc.
Ejercicios.
1). Para realizar los siguientes ejercicios de funciones, primero añade la fecha de nacimiento (f_nac) a cada empleado (con ALTER TABLE). Después, pone fechas de nacimiento a los empleados existentes (con diferentes UPDATE).
2). Muestra todos los datos de la tabla de empleados y, además, de cada uno de ellos: la longitud de su nombre, la comisión en tanto por 1 (en la tabla está como %), el día de la semana en que nacieron, la fecha de nacimiento expresado en formato: 19 de 3 de 1970
3). Muestra los nombres de los departamentos en minúscula y mayúscula.
-
f) Funciones de agregado
Las funciones que hemos visto muestran UN RESULTADO POR CADA FILA de la tabla. Las funciones de agregado que vamos a ver muestran UNO ÚNICO RESULTADO PARA TODA LA TABLA.
Ejemplo:
SELECT MAX(precio), MIN(precio), AVG(precio), SUM(precio), COUNT(*), COUNT(precio) FROM libros;MAX(precio) MIN(precio) AVG(precio) SUM(precio) COUNT(*) COUNT(precio) 26.00 10:50 17.00 136.0 8 6 Explicación:
- MAX(precio): Calcula el máximo precio entre todas las filas (entre todos los libros)
- MIN(precio): Calcula el mínimo precio
- AVG(precio): Calcula el precio medio (entre aquellos que el precio no es NULL)
- SUM(precio): Calcula la suma de todos los precios
- COUNT(*): Cuenta cuántas filas (cuántos libros en este caso) hay
- COUNT(precio): Cuenta cuántas filas (cuántos libros) tienen el precio no NULL.
Filtro
Si en la SELECT hubiese un WHERE, los cálculos se aplicarían sólo teniendo en cuenta las filas seleccionadas en ese WHERE.
Por ejemplo estas dos consultas no darán el mismo resultado:
| codigo | articulo | precio |
|---|---|---|
| 1 | Tomates | 3.50 |
| 2 | Patatas | 4.00 |
| 3 | Manzanas | 2.00 |
| 4 | Cebollas | 1.50 |
SELECT SUM(precio), COUNT(*) FROM articulos;
SELECT SUM(precio), COUNT(*) FROM articulos WHERE precio > 2.00;
El primero devolverá: 11.00 y 4, ya que hay 4 artículos y la suma de sus precios es 11.00.
| Sum(precio) | COUNT(*) |
|---|---|
| 11.00 | 4 |
El segundo devolverá: 7.50 y 2, ya que sólo hay 2 artículos con precio mayor que 2.00 (Tomates y Patatas) y la suma de sus precios es 7.50.
| Sum(precio) | COUNT(*) |
|---|---|
| 7.50 | 2 |
Operadores y funciones de agregado
Las funciones de agregado pueden utilizarse con operadores y otras funciones de agregado. Por ejemplo:
SELECT SUM(precio_venta - precio_coste)
FROM artículos;
SELECT MAX(precio_venta) - MIN(precio_coste)
FROM artículos;
Ejercicios (Funciones de agregado)
A partir de ahora trabajaremos con la base de datos lliga1213. Para crearla (con todas sus tablas y registros) descarga el escript lliga1213.sql. Echa un vistazo por las tablas y columnas para familiarizarte con esa BD y lee el archivo que explica el contenido de la base de datos. Después, resuelve los siguientes ejercicios. Te aconseje que tengas delante del esquema de las tablas con las respectivas columnas del archivo que explica la base de datos.
Entidad Relación

Esquema relacional

Advertencia
Los 2 primeros no son de funciones de agregado pero nos servirán para entrar en contacto en esta base de datos.
Ejercicios 1
Muestra toda la estadística de aquellos goleadores que han marcado algún penalti.
Ejercicio 2
De cada partido muestra la jornada, el equipo de casa y el de afuera, los goles de cada equipo, el total de goles, la posesión del equipo de casa y la del equipo de afuera. Pone nombres coherentes en las columnas.
Ejercicio 3
Goles marcados por el pichichi (sólo los goles; el nombre del jugador no).
Ejercicios 4
Media de goles por partido en toda la liga.
Ejercicio 5
Muestra los siguientes sueldos: el más caro, el más barato y el promedio.
Ejercicio 6
Total de goles marcados en toda la liga.
Advertencia
Nota: esta información está en 2 tablas: en los resultados de los partidos y en los goles marcados por cada goleador. No cuadra porque hay goles que no les han marcado los goleadores (sino porteros, defensas, en propia puerta...).
- Total de goles marcados en todos los partidos
- Total de goles marcados por todos los goleadores.
Ejercicio 7
Muestra cuántos partidos hay, cuántos se han jugado y cuántos no se han jugado.
Ejercicio 8
Muestra la diferencia entre el mayor presupuesto y el menor.
Ejercicio 9
Muestra la fecha más antigua y la más reciente de las jornadas.
La cláusula FROM
Esta cláusula la hemos utilizado ya. Sirve para decir de qué tabla/s vamos a mostrar los datos de la sentencia SELECT.
Ahora bien, hasta ahora sólo hemos hecho consultas que se obtienen de una única tabla, pero más adelante veremos cómo hacer sentencias para obtener información de más de una tabla. En esos casos después de la palabra clave FROM, pondremos todas las tablas necesarias separadas por comas.
SELECT nombre, precio
FROM artículos;
Aquí tenemos un ejemplo de cómo se haría, pero no te preocupes por entenderlo ahora, ya veremos más adelante:
SELECT proveedores.nombre AS “Nombre proveedor”,
articulos.descripcion AS “Descr.artículo”
FROM proveesores, proveer, articulos
WHERE proveedores.codigo = proveer.pro
AND proveer.art = articulos.codigo;
| Nombre proveedor | Descr. artículo |
|---|---|
| ANECOOP | tomates |
| COPSEMAR | arroz |
| UNIANA | naranjas |
FROM
La cláusula FROM es obligatoria en las sentencias SELECT, salvo casos muy especiales como, por ejemplo, mostrar el valor de variables del sistema, alguna operación matemática o llamada a una función
SELECT SYSDATE(); -- Función del sistema que muestra la fecha y hora actual
SELECT 10/3; -- operación matemática
SELECT myfunction(); -- llamada a una función (se debe haber creado previamente)
La cláusula ORDER BY
Esta clausula no es obligatoria, pero si la ponemos debe ir siempre al final de la sentencia SELECT. Esto asegura que el orden de las filas del resultado de la consulta sea el que nosotros queramos, cabe recordar que una de las premisas de los sistemas de bases de datos es que no se garantiza el orden de las filas a menos que se especifique explícitamente.
SELECT editorial, precio, título
FROM libro
ORDER BY editorial DESC, título ASC;
| editorial | precio | título |
|---|---|---|
| Plaza & Janés | 26.00 | Aplique SQL |
| Plaza & Janés | 17.00 | Atlas de España |
| Planeta | 12:00 | Cañas y barro |
| McGraw-Hill | 10:50 | Cinco horas con Màrius |
| McGraw-Hill | 23.50 | Don Quijote |
| Altaya | 21.00 | El nombre de la rosa |
| Altaya | 15:00 | La odisea |
| Altaya | 11.00 | La Barraca |
Tipo de orden
Podemos utilizar:
- ASC: Orden ascendente (de menor a mayor, de A a Z, de 1 a 10, etc.)
- DESC: Orden descendente (de mayor a menor, de Z a A, de 10 a 1, etc.)
Si no se indica nada, por defecto es ASC (ascendente).
Orden por número de columna
Para indicar la columna en el ORDER BY, en lugar de poner el nombre de la columna podemos poner el número en el que aparece esa columna en la cláusula SELECT. El resultado será el mismo. En nuestro ejemplo:
SELECT editorial, precio, título
FROM libros
ORDER BY 1 DESC, 3 ASC
Advertencia
Para utilizar el orden por número de columna es importante tener en cuenta que: las columnas se numeran desde 1, no desde 0. Por tanto, la primera columna de la cláusula SELECT es la número 1, la segunda es la número 2, etc.
La cláusula ORDER BY va al final de todo de la sentencia SELECT, pero existen otras cláusulas entre el FROM y el ORDER BY que ya iremos viendo (como GROUP BY, HAVING y UNION).
Ejercicios ORDER BY
Ejercicio 1
Muestra el nombre largo de cada equipo y su presupuesto, ordenado por el presupuesto, de menor a mayor.
Ejercicio 2
De cada partido, muestra la jornada, el equipo de casa y sus goles, primero saldrán los que han marcado más goles.
Ejercicio 3
De cada partido, muestra la jornada, el equipo de casa y sus goles. Estará ordenado por equipo (de menor a mayor). Los partidos de cada equipo estarán ordenados de más goles a menos.
Ejercicio 4
Muestra todos los datos de los partidos pero primero saldrán los partidos que se hayan marcado más goles. En caso de igualdad, saldrán primero los que se marcaran más goles en casa. En caso de igualdad saldrán ordenados por el código del equipo de casa (de menor a mayor). En caso de igualdad saldrán ordenados por la jornada.
Resultados de consultas
El resultado de una consulta SQL es similar a una tabla de la BD, con filas y columnas. En lugar de mostrar ese resultado por pantalla, podemos aprovecharlo para varias cosas:
-
Insertarlo en otra tabla existente (ya lo hemos visto en el apartado del inserto):
INSERT INTO ventas_febrero -- Tabla ya existente SELECT * FROM ventas WHERE mes = 2;Estamos añadiendo en la tabla ventas_febrero (que ya existía) los registros de la tabla ventas que cumplían una determinada condición. Los campos de la tabla ventas_febrero deberán coincidir con cantidad y tipos de las columnas de la cláusula select.
-
Crear otra tabla con las filas y columnas seleccionadas:
Estamos creando la tabla socios_sin_tel con 2 campos (código_socio y nombre_socio) y con los datos resultantes de aplicar la “SELECT” en la tabla socios:CREATE TABLE socios_sin_tel AS -- Tabla que creamos ahora SELECT código_socio, nombre_socio FROM socios WHERE teléfono IS NULL -
Crear una vista con las filas y columnas seleccionadas. Lo veremos más adelante. Ya veremos más adelante, pero sería así:
CREATE VIEW socios_sin_tel AS SELECT código_socio, nombre_socio FROM socios WHERE teléfono IS NULL
Ni estaba creada la tabla socios_sin_tel ni la estamos creando ahora, sino que le estamos poniendo un nombre al resultado de la select, de forma que podremos utilizarlo como si fuera otra tabla pero no ocupa espacio en disco duro, ya que las filas son las mismas que la tabla original (socios).
Ejercicios resultados de consultas
En los siguientes ejercicios veremos los pasos para pasar los datos de una tabla a otra/s, de diversas formas.

Ejercicios. Resultados de consultas (BD instituto)
- Crea la BD instituto.
- Crea en ella la tabla alumnos con los campos código (entero), nombre y estudios (4 caracteres).
- Introduce 3 alumnos con estudios de PCPI, 3 de ESO y 3 de DAM.
- A partir de esa tabla, crea la tabla a_dam con los alumnos de DAM (código y nombre) utiliza la sentencia de crear una tabla a partir de una select.
- Crea la tabla a_eso con código (entero) y nombre
- Introduce 3 alumnos de ESO en a_eso (con códigos que no estén en tabla de alumnos).
- Copia a los alumnos de ESO de la tabla alumnos en la tabla a_eso (con la sentencia de inserción de filas a partir de una select).
- Borra de la tabla alumnos los de ESO y DAM.
- La tabla alumnos ahora debe decirse a_pqpi
- Elimina el campo estudios de la tabla a_pqpi
Mostrar sólo las filas distintas (DISTINCT)
A veces, una consulta sacará filas repetidas.
Ejemplo de filas repetidas
Por ejemplo, si tenemos una tabla de autores con los siguientes datos:
SELECT país, lengua
FROM autores
Filas repetidas
| país | lengua |
|---|---|
| España | Castellano |
| España | Catalán |
| Argentina | Castellano |
| España | Catalán |
| España | Vasco |
| Argentina | Castellano |
Si después de la palabra SELECT ponemos DISTINCT, no mostrará esas filas repetidas:
Uso de DISTINCT
SELECT DISTINCT país, lengua
FROM autores
DISTINCT
| país | lengua |
|---|---|
| España | Castellano |
| España | Catalán |
| España | Vasco |
| Argentina | Castellano |
DISTINCT
Aunque la cláusula SELECT tenga más de un campo (como en el ejemplo anterior), sólo se pone un DISTINCT, el cual descartará las filas repetidas en todos los campos de la SELECT.
Cuidado se entiende por fila duplicada aquella en que TODOS sus campos son iguales. En el ejemplo anterior, la fila con país=España y lengua=Catalán aparece 2 veces, por tanto se considera una fila repetida y sólo se muestra una vez.
La función de agregado COUNT también admite el DISTINCT. Se usa cuando queremos contar cuántos elementos distintos tenemos. Por ejemplo:
SELECT COUNT(*), COUNT(pais), COUNT(DISTINCT pais), COUNT(DISTINCT(lengua))
FROM autores
| count(*) | count(país) | count(distinct país) | count(distinct lengua) |
|---|---|---|---|
| 6 | 6 | 2 | 3 |
Ejercicios DISTINCT
Ejercicio 1
Muestra los departamentos que tienen algún empleado. En la tabla dept están todos los departamentos pero quizá alguno no tiene empleados. Por tanto, deberás sacarlo a partir de la tabla emp. Que no aparezcan repetidos los departamentos.
Ejercicio 2
Muestra las parejas de comisión y departamento (de la tabla de empleados) sin que aparezcan parejas repetidas.
Ejercicio 3
Muestra en cuántos pueblos hay departamentos.
Ejercicio 4
De la tabla jugadores saca los códigos de los equipos sin repetidos.
Ejercicio 5
De la tabla equipos saca los cósigos de las ciudades sin repetidos.
La cláusula WHERE
La cláusula WHERE se utiliza cuando no queremos mostrar datos de todas las filas de la tabla, sino sólo algunas. Actua como un filtro que se aplicada a cada una de las filas de la tabla indicada en FROM. De manera que solo las que cumplen el filtro serán devueltas.
Si tenemos los siguientes datos:
| nombre | edad |
|---|---|
| Juan | 21 |
| Pep | 17 |
| Juanito | 20 |
| Pepa | 16 |
| Toni | 15 |
| María | 17 |
| Juanita | 23 |
| Sole | NULL |
Por ejemplo: Muéstrame a los alumnos menores de edad
consulta con filtro
SELECT nombre, edad
FROM alumnos
WHERE edad < 18 -- Condición de investigación: edad < 18
resultado
| nombre | edad |
|---|---|
| Pep | 17 |
| Pepa | 16 |
| Toni | 15 |
| María | 17 |
| () en el resultado nunca* puede haber ninguna fila que contradiga el filtro. |
Al aplicar el filtro fila a fila el sistema gestor habrá hecho algo como:
| nombre | edad | filtro |
|---|---|---|
| Juan | 21 | ❌ |
| Pep | 17 | ✅ |
| Juanito | 20 | ❌ |
| Pepa | 16 | ✅ |
| Toni | 15 | ✅ |
| María | 17 | ✅ |
| Juanita | 23 | ❌ |
| Sole | NULL | ❌ |
lógica trievaluada
La cláusula WHERE consta de la palabra clave WHERE seguida de una condición de búsqueda que especifica las filas a recuperar. Por cada fila de la tabla seleccionada, la condición de búsqueda puede producir uno de estos tres resultados:
- Si la condición de investigación es true (cierta), la fila SÍ que sale en la consulta.
- Si la condición de investigación es false (falsa), la fila NO sale en la consulta.
- Si la condición de investigación tiene un valor NULL, la fila NO sale en la consulta.
En el ejemplo anterior, los alumnos que no tenían puesta su edad (tenían un NULL), la condición de: NULL<18 tiene como resultado el valor NULL y, por tanto, esos alumnos NO saldrían en la consulta. Ya veremos más adelante cómo consultar en la WHERE si un campo tiene el valor NULL.
La condición de investigación es lo que podemos poner dentro de la cláusula WHERE (o del HAVING, otro filtro que ya veremos más adelante). ¿Qué podemos poner en una condición de investigación?
- Test de comparación
- Test de rango
- Test de pertenencia a un conjunto
- Test de correspondencia con patrón
- Test de valor nulo.
Además, la condición de investigación puede estar compuesta (tener varias condiciones). Para ello utilizaremos los operadores relacionales AND, OR y NOT.
Vemos cada uno de estos test así como las condiciones de búsquedas compuestas.
-
Test de comparación ( =, <>, <, <=, >, >= )
Compara expresiones (nombres de columnas, constantes, expresiones aritméticas o funciones).
Ejemplos:
... WHERE iva < 16 ... WHERE nombre = 'Pep' ... WHERE (entradas - salidas) <> saldo ... WHERE precio\_euros > (precio\_ptas / 166.386) -
Test de rango (BETWEEN)
Esto mostrará a los socios con un préstamo en la primera quincena de febrero de 2013. La condición contraria sería:SELECT código_socio FROM préstamos WHERE fecha BETWEEN “2013/02/01” AND “2013/02/15”WHERE fecha NOT BETWEEN “2013/02/01” AND “2013/02/15”. -- O bien: WHERE NOT (fecha BETWEEN 01/02/2013” AND “2013/02/15”).BETWEEN no es realmente necesario, ya que podríamos reemplazarlo con expresiones con AND y OR:
-- BETWEEN B AND C -- es equivalente a: WHERE (A >= B) AND (A <= C)-- NOT BETWEEN B AND C -- es equivalente a: WHERE (A < B) OR (A > C) -
Test de pertenencia a un conjunto (IN)
Mostrará los datos de los préstamos que sean de alguna de esas fechas.SELECT código_libro, código_socio, fecha_pre FROM préstamos WHERE fecha_pre IN ('2015/09/02', '2015/04/05', '2016/01/09')código_libro código_socio fecha_pre 0001 1 2015/09/02 0002 4 09/01/2016 0002 3 05/04/2015 0007 1 2015/09/02 Para obtener los demás resultados, debería utilizarse el NOT IN (pero recordemos que no saldrían aquellos préstamos que tienen un NULL en su fecha).
Al igual que el test BETWEEN, el test IN tampoco es necesario, ya que la condición:
-- WHERE x IN (a, b, c)... -- es equivalente a: WHERE (x = a) OR (x = b) OR (x = c)... -
Test de correspondencia con patrón (LIKE)
Se utiliza para buscar cadenas de caracteres que se ajusten a un patrón.
nombre_columna [NOT] LIKE patrónEl patrón es una cadena que puede incluir uno o más caracteres comodines:
_(símbolo barra baja) a cualquier carácter (pero 1 y sólo 1).%(símbolo del porcentaje) a cualquier secuencia de 0, 1 o más caracteres.
Ejemplo 1
Sacar nombre y apellidos de los alumnos que tengan de apellido Escrivá o Escribano
|nombre|apellidos| | :-: | :-: | |Pep|Pons Escrivá| |Pepa|Escribano García|SELECT nombre, apellidos FROM alumnos WHERE apellidos LIKE '%Escri_á%'Ejemplo 2
Sacar nombre y apellidos de los alumnos que tienen un nombre de 3 letras
SELECT nombre, apellidos FROM alumnos WHERE nombre LIKE '___'nombre apellidos Pep Pons Escrivá Roque Garcia y Garcia Pueden localizarse cadenas que no se ajustan a un patrón utilizando NOT LIKE.
Si el valor de esa columna en alguna fila es NULL, tanto si ponemos LIKE como NOT LIKE, la fila no saldrá en el resultado.
Carácter de escape Si quisiéramos buscar si aparece el símbolo de
%o_en una cadena de texto, habría que utilizar un carácter de escape, que en MySQL es “\”.Ejemplo: Halla el título de los libros que contengan el símbolo del porcentaje.
Esto sacará títulos como: "El 50% de los alumnos son la mitad"SELECT título FROM libros WHERE título LIKE '%\%%' -
Test de valor nulo (IS NULL)
Un campo de una tabla que no contiene ningún valor se dice que contiene un valor nulo. No es que el valor sea cero o sea una cadena vacía, sino que no tiene valor.
Por ejemplo, pondremos valores nulos en los siguientes casos:
- Cuando desconocemos el valor (por ejemplo, la fecha de nacimiento de un cliente).
- Cuando no tiene valor (por ejemplo, el correo electrónico de alguien que no lo tiene).
- Cuando carece de sentido el valor (por ejemplo, el nombre del padre de un alumno mayor de edad).
Para consultar dónde aparecen valores nulos es necesario usar una sentencia de comparación específica “IS NULL”. No es correcto realizar comparaciones con el comparador de igualdad “=”. Por ejemplo, si queremos saber a los clientes que no nos deben nada o aquellos que no sabemos lo que nos deben, haríamos:
código nombre deuda 3 Pep 0 5 Pepa NULL 7 María NULL Y para consultar dónde aparecen valores no nulos, usaremos IS NOT NULL:SELECT código, nombre, deuda FROM socios WHERE deuda = 0 OR deuda IS NULLQue es lo mismo que:SELECT código, nombre, deuda FROM socios WHERE deuda IS NOT NULL... WHERE NOT (deuda IS NULL) -
Lógica trivaluada
Debe tenerse en cuenta que los valores NULL crean una lógica trivaluada para las condiciones de investigación en SQL. Es decir, cuando SQL compara los valores de dos expresiones en el test de comparación, para una fila determinada, pueden producirse tres resultados: TRUE, FALSE o NULL.
- Si la comparación es cierta -> el resultado es TRUE.
- Si la comparación es falsa -> el resultado es FALSE.
- Si el valor de algún campo de la comparación es NULL -> el resultado es NULL.
La cláusula WHERE sólo seleccionará los resultados TRUE.
Veámoslo con ejemplos. Supongamos que tenemos la siguiente tabla de alumnos:
nombre edad Pep 20 Pepa NULL Pepepito 15 Para mostrar a los alumnos mayores de edad haremos:
SELECT nombre FROM alumnos WHERE edad >= 18; // PepPara mostrar a los menores de edad, habría que indicar la condición contraria:
SELECT nombre FROM alumnos WHERE NOT (edad >= 18); // PepetPero vemos que Pepa no ha salido ni como menor de edad ni mayor. Para mostrar aquellos que no tienen edad, debemos utilizar IS NULL:
SELECT nombre FROM alumnos WHERE edad IS NULL; // PepaY para mostrar a los que sí tienen edad:
Si quisiéramos mostrar a los menores de edad pero también a los que no tienen edad (edad NULL), deberíamos hacer:SELECT nombre FROM alumnos WHERE edad IS NOT NULL; // Pep y PepetSELECT nombre FROM alumnos WHERE edad < 18 OR edad IS NULL; // Pepa y PepetCuidado con el uso de NULL en WHERE
Hay que tener cuidado y NO utilizar la siguiente condición:
... WHERE teléfono = NULL; -- ❌Es decir: para comparar con el NULL es necesario usar IS y no el signo =.
-
Condiciones de investigación compuestas: AND, OR y NOT
Ya hemos visto en algún ejemplo que en el apartado WHERE ya han aparecido algunos operadores relacionales. Los que usa MySQL son AND, OR y NOT. Es decir: las condiciones de investigación pueden estar compuestas y así combinar diferentes condiciones simples. También podemos hacer uso de paréntesis, sobre todo cuando queremos romper el orden de prioridad de los operadores, que es el siguiente:
Prioridad de operadores
1). NOT
2). AND
3). OR
La sentencia SELECT calculará esa condición compuesta por cada fila de la tabla y devolverá aquellas filas que el resultado sea verdadero.
Ejemplo 1
Mostrar los alumnos que son de Sueca y que nacieron antes de 1970
Consulta
SELECT nombre, edad FROM amigos WHERE ciudad = 'Sueca' AND fecha_nace < '01/01/1970'Ejemplo 2
Mostrar los libros de Joan Fuster o que son de tipo asignatura
Consulta
SELECT título, editorial FROM libros WHERE autor = 'Joan Fuster' OR tipo = 'asig'Ejemplo 3
Mostrar el nomre y la nacinoalidad de los autores que su nombre no contiene la palabra Delibes
Consulta
SELECT nombre, nacionalidad FROM autores WHERE NOT (nombre LIKE '%Delibes%')Ejemplo 4
Mostrar los discos de rock o pop y que no están en castellano, catalán o inglés
Consulta
SELECT titulo_disco, grupo FROM discos WHERE (tipo = 'rock' OR tipo = 'pop') AND NOT (lengua IN ('castellano', 'catalán', 'inglés'))
Ejercicios WHERE EMPRESA
Ejercicios. WHERE (BD empresa)
A partir de la base de datos empresa, resuelve los siguientes ejercicios:
- Muestra nombre y comisión de aquellos empleados que NO tengan comisión (piensa que puede haber empleados con comisión 0 y empleados con comisión NULL).
- Muestra nombre y comisión de los empleados que sean del departamento 2 con una comisión superior al 10%.
- Muestra nombre y comisión de los empleados cuya comisión es entre el 20 y el 50%. Hazlo de 2 formas: con BETWEEN y sin BETWEEN.
- Muestra el nombre de los empleados de los departamentos 2, 5 y 6. Muestra también el departamento de cada uno. Hazlo de 2 formas: con IN y sin IN.
- Muestra todos los datos de los empleados que el nombre empiece por A, que terminan con E y que la tercera letra de su nombre sea una I.
EJERCICIOS. WHERE LLIGA1213
Ejercicio 1
Partidos que ha perdido al Barça (código 'bar') jugando en casa.
Ejercicio 2
Partidos que ha perdido al Barça jugando fuera.
Ejercicio 3
Cantidad de partidos que ha perdido el Barça.
Ejercicio 4
Partidos en los que se han marcado más de 5 goles.
Ejercicio 5
Qué jornadas se jugaron en febrero.
Ejercicio 6
¿Cuántos partidos todavía no ha jugado el Valencia (no ha jugado si no están puestos los goles).
Ejercicio 7
Partidos donde el Madrid (código 'rma') ha recibido 3 o más goles.
Ejercicio 8
Partidos en los que el Madrid ha perdido por más de un gol de diferencia.
Ejercicio 9
Partidos en los que un equipo ha tenido más del 60% de posesión.
Ejercicio 10
Partidos en los que un equipo ha tenido más del 60% de posesión y ha perdido el partido.
Ejercicio 11
Muestra la quiniela de la primera jornada (equipo casa, equipo fuera, 1x2). Deberás utilizar la función “IF”.
Ejemplo de uso: IF
Tabla Alumnos:
| nombre | apellidos | edad |
|---|---|---|
| Pep | García | 20 |
| Pepito | Martí | 17 |
| Pepa | Granillo | 18 |
| Pepona | Albores | 19 |
SELECT nombre, apellidos, IF(edad >= 18, 'Sí', 'No') AS 'Mayor de edad'
FROM alumnos
| nombre | apellidos | Mayor de edad |
|---|---|---|
| Pep | García | Sí |
| Pepito | Martí | No |
| Pepa | Granillo | Sí |
| Pepona | Albores | Sí |
Podemos usar una función IF dentro de otra. Función IF
cláusula GROUP BY
Supongamos que tenemos esta tabla de libros:
Tabla libros
| título | editorial | precio |
|---|---|---|
| La odisea | Altaya | 15.00 |
| Cinco horas con Màrius | McGraw-Hill | 10.50 |
| La Barraca | Altaya | 11.00 |
| Cañas y barro | Planeta | 12.00 |
| El nombre de la rosa | Altaya | 21.00 |
| Don Quijote | McGraw-Hill | 23.50 |
| Atlas de España | Plaza & Janés | 17.00 |
| Aplique SQL | Plaza & Janés | 26.00 |
Vemos que cada libro pertenece a una editorial (y que una editorial tiene muchos libros). La tabla libros tiene tantos libros como filas. Pero imagina que no queremos obtener información de cada libro (de cada fila) sino de cada editorial (de cada GRUPO de libros de la misma editorial). Por ejemplo, de cada editorial queremos saber (además del nombre): el precio del libro más caro de esa editorial, el precio del libro más barato de esa editorial, el precio medio de los libros de esa editorial, la suma de los precios de todos los libros de esa editorial y la cantidad de libros que tiene esa editorial.
Es decir: querremos obtener la siguiente información:
Tabla de resultados
| editorial | precio máximo | precio mínimo | precio medio | suma de precios | cantidad de libros |
|---|---|---|---|---|---|
| Altaya | 21.00 | 11.00 | 15.67 | 47.00 | 3 |
| McGraw-Hill | 23.50 | 10:50 | 17.00 | 34.00 | 2 |
| Planeta | 12:00 | 12:00 | 12:00 | 12:00 | 1 |
| Plaza & Janés | 26.00 | 17.00 | 21.50 | 43.00 | 2 |
¿Cómo obtenemos esto con una sentencia select?
Deberemos decir a la select que no muestre información de cada fila (de cada libro) sino de cada grupo de filas de la misma editorial. Y, para mostrar la información, usaremos unas funciones de MySQL que actúan sobre grupos de filas (funciones de agregado): max, min, avg, sum, count.
Es decir: deberemos decir a la select que, internamente, agrupe los libros por la editorial...
Tabla de liboros ordenada por editorial para agrupar...
| título | editorial | precio |
|---|---|---|
| La odisea | Altaya | 15:00 |
| La Barraca | Altaya | 11.00 |
| El nombre de la rosa | Altaya | 21.00 |
| Cinco horas con Màrius | McGraw-Hill | 10:50 |
| Don Quijote | McGraw-Hill | 23.50 |
| Cañas y barro | Planeta | 12:00 |
| Atlas de España | Plaza & Janés | 17.00 |
| Aplique SQL | Plaza & Janés | 26.00 |
... y, así, obtener una fila de resultados por cada grupo. Es decir, la sentencia sería esta:
SELECT editorial, MAX(precio), MIN(precio), AVG(precio), SUM(precio), COUNT(*)
FROM libros
GROUP BY editorial
Esta consulta nos devolverá una fila por cada editorial, con el precio máximo, mínimo, medio, la suma de los precios y la cantidad de libros de esa editorial.
Expresiones en funciones de agregado
Las funciones de agregado pueden recibir expresiones, no sólo nombres de columnas. Por ejemplo, si quisiéramos calcular el beneficio de cada libro (precio - precio_compra), podríamos hacer:
SELECT editorial, MAX(precio – precio_compra)
FROM libros
GROUP BY editorial
Contar filas de un grupo
Si queremos contar las filas de cada grupo, podemos utilizar la función de agregado COUNT. Esta función cuenta las filas que cumplen una condición. Si no se le pasa ningún parámetro, cuenta todas las filas del grupo. Si se le pasa un nombre de columna, cuenta sólo aquellas filas donde ese campo no es NULL.
SELECT editorial, COUNT(*)
FROM libros
GROUP BY editorial
COUNT(precio): cuenta las filas del grupo donde el precio no es NULL.
SELECT editorial, COUNT(precio)
FROM libros
GROUP BY editorial
La sintaxis de la sentencia selecSELECT completa con la cláusula GROPU BY es:
SELECT ... /*Aquí podremos poner o bien los nombres de las columnas por las que estamos agrupando o bien funciones de agregado (max, min, avg, sum, count) o expresiones.*/
FROM ...
WHERE ...
GROUP BY ... /* Aquí pondremos el nombre de la columna (o columnas separadas por comas) por la que queremos agrupar. Es decir: todas las filas de ese grupo tendrán el mismo valor de esa columna. */
Cuidado con el uso de GROUP BY
Si utilizamos funciones de agregado, todos los demás campos de la cláusula SELECT deben aparecer también en la cláusula GROUP BY. Es decir: si agrupamos por editorial, no podemos mostrar el título del libro, ya que cada editorial puede tener varios títulos y no tendría sentido mostrar un título cualquiera de esa editorial.
SELECT editorial, titulo, MAX(precio)
FROM libros
GROUP BY editorial
Esto daría error porque estamos agrupando por editorial pero no por título. No se puede agrupar por una columna y mostrar otra que no esté agrupada.
Recordemos que si usamos funciones de agregado pero no ponemos el GROUP BY, sólo nos mostrará una única fila de resultados para toda la tabla:
SELECT MAX(precio), MIN(precio), AVG(precio), SUM(precio), COUNT(*), editorial
FROM libros
Como en este caso no estamos agrupando por la editorial, no tiene sentido que nos muestre la editorial, ya que mostraría el nombre de una editorial cualquiera de toda la tabla. No daría error, pero no tendría sentido.
| MAX(precio) | MIN(precio) | AVG(precio) | SUMO(precio) | COUNTO(*) |
|---|---|---|---|---|
| 26.00 | 10:50 | 17.00 | 136.0 | 8 |
links a W3Schools
Agrupación por más de una columna
Tabla alumnos
Supongamos que tenemos la siguiente tabla de alumnos:
| ALUMNOS | |||||
|---|---|---|---|---|---|
| núm | nombre | curso | grupo | pueblo | edad |
| 1 | Pep | 1 | A | Sueca | 17 |
| 2 | Pepa | 1 | A | Sueca | 17 |
| 3 | Pepito | 1 | A | Tabernas | 18 |
| 4 | Pepita | 1 | A | Tabernas | 19 |
| 5 | Pepot | 1 | B | Sueca | 17 |
| 6 | Pepota | 1 | B | Sueca | 18 |
| 7 | Pepi | 1 | B | Sueca | 17 |
| 8 | José | 1 | B | Tabernas | 17 |
| 9 | Josepa | 2 | A | Sueca | 18 |
| 10 | Josepet | 2 | En | Sueca | 18 |
| 11 | Josefa | 2 | A | Tabernas | 21 |
| 12 | Josepot | 2 | B | Tabernas | 19 |
También podemos agrupar por más de una columna. En ese caso, cada grupo tendrá los mismos valores en cada una de esas columnas.
Cuantas más columnas ponemos en el group by, más grupos saldrán (pero con menos filas cada uno, claro).
Veámoslo con ejemplos de la tabla alumnos:
Número de alumnos por curso, máximo y mínimo de edad en cada curso
SELECT curso, count(*), min(edad), max(edad)
FROM alumnos
GROUP BY curso
| curso | count(*) | min(edad) | max(edad) |
|---|---|---|---|
| 1 | 8 | 17 | 19 |
| 2 | 4 | 18 | 21 |
Del curso 1º hay 8 alumnos y del curso 2º hay 4 alumnos
Número de alumnos por curso y grupo, máximo y mínimo de edad en cada curso y grupo
SELECT curso, grupo, count(*), min(edad), max(edad)
FROM alumnos
GROUP BY curso, grupo
| curso | grupo | count(*) | min(edad) | max(edad) |
|---|---|---|---|---|
| 1 | A | 4 | 17 | 19 |
| 1 | B | 4 | 17 | 18 |
| 2 | A | 3 | 18 | 21 |
| 2 | B | 1 | 19 | 19 |
En esta tabla podemos ver que del curso 1º, grupo En hay 4 alumnos y del curso 1º, grupo B hay 4 alumnos. Del curso 2º, grupo En hay 3 alumnos y del curso 2º, grupo B hay 1 alumno.
Número de alumnos por curso, grupo y pueblo, máximo y mínimo de edad en cada curso, grupo y pueblo
SELECT curso, grupo, pueblo, count(*), min(edad), max(edad)
FROM alumnos
GROUP BY curso, grupo, pueblo
| curso | grupo | pueblo | count(*) | min(edad) | max(edad) |
|---|---|---|---|---|---|
| 1 | A | Sueca | 2 | 17 | 17 |
| 1 | A | Tabernas | 2 | 18 | 19 |
| 1 | B | Sueca | 3 | 17 | 18 |
| 1 | B | Tavermas | 1 | 17 | 17 |
| 2 | A | Sueca | 2 | 18 | 18 |
| 2 | B | Tabernas | 1 | 19 | 19 |
Del curso 2, grupo A que sean de Sueca hay 2 alumnos
Cuidado con el uso de GROUP BY - no poner campos en la cláusula SELECT
Si utilizamos funciones de agregado, todos los demás campos de la cláusula SELECT deben aparecer también en la cláusula GROUP BY. Es decir: si agrupamos por curso, el curso debe aparecer en la cláusula SELECT.
Vamos a utilizar el primer ejemplo de antes pero sin poner el campo curso en la cláusula SELECT:
SELECT count(*), min(edad), max(edad)
FROM alumnos
GROUP BY curso
Esta consulta no da error pero obtenemos el siguiente resultado:
| count(*) | min(edad) | max(edad) |
|---|---|---|
| 8 | 17 | 19 |
| 4 | 18 | 21 |
EL resultado es correcto, pero no tiene sentido. Nos dice que hay 8 alumnos y 4 alumnos, pero no sabemos a qué curso pertenecen esos alumnos. La información no no es útil
Cuidado con el uso de GROUP BY - poner campos de más en la cláusula SELECT
Ahora vamos con este ejemplo, al contrario que el anterior ahora tenemos un campo en la cláusula SELECT nombre que no está en la cláusula GROUP BY:
SELECT curso, grupo, nombre, COUNT(*)
FROM alumnos
GROUP BY curso, grupo
Esto daría error porque estamos agrupando por curso y grupo pero no por nombre. No se puede agrupar por una columna y mostrar otra que no esté agrupada.
Si analizamos la consulta veremos que vuelve a no tener sentido. Por ejemplo, si agrupamos por curso y grupo sabemos que de 1º A hay 4 alumnos, pero ¿qué nombre queremos mostrar?¿de cuál de esos 4 alumnos? ¿del primero? ¿del último? ¿de uno al azar? No tiene sentido mostrar un nombre cualquiera de un grupo de alumnos.
EJERCICIOS. GROUP BY (BD liga1213)
Ejerccicio 1
Muestra de cada equipo: el código, sueldo máximo, mínimo, la suma de todos los sueldos, cuántos jugadores hay, de cuántos jugadores se conoce el sueldo, la media de sueldos entre los que sabemos el sueldo y la media de sueldos entre todos los jugadores.
Ejercicio 2
Muestra cuántos jugadores tiene cada equipo en cada posición.
Ejercicio 3
Goles marcados en total en cada jornada.
Ejercicio 4
Media de goles por partido en cada jornada.
Ejercicio 5
Goles marcados por el pichichi de cada equipo. Es decir: es necesario mostrar el código del equipo y los goles marcados por su máximo goleador.
Ejercicio 6
Goles marcados en total por cada equipo en casa.
Ejercicio 7
Goles que ha recibido en total a cada equipo como visitante.
Ejercicio 8
¿Cuántos partidos ha ganado cada equipo jugando en casa
La cláusula HAVING
Si la cláusula WHERE descartaba filas, la cláusula HAVING descarta grupos. Es decir: en la condición de filtrado del HAVING indicaremos qué debe cumplir un grupo para que no sea descartado. No puede haber cláusula HAVING si no existe GROUP BY. Importante tener en cuenta que el filtro de la cláusula HAVING se aplica después de que se hayan agrupado las filas. Es decir: la cláusula HAVING actúa sobre los grupos de filas y no sobre las filas individuales.
SELECT ...
FROM ...
WHERE ...
GROUP BY ...
HAVING [condición_de_búsqueda]
Volvamos al ejemplo de la tabla de libros, recordemos:
consulta
SELECT editorial,
MAX(precio),
MIN(precio),
AVG(precio),
SUM(precio),
COUNT(*)
FROM libros
GROUP BY editorial
resultado de la consulta
| editorial | precio máximo | precio mínimo | precio medio | suma de precios | cantidad de libros |
|---|---|---|---|---|---|
| Altaya | 21.00 | 11.00 | 15.67 | 47.00 | 3 |
| McGraw-Hill | 23.50 | 10:50 | 17.00 | 34.00 | 2 |
| Planeta | 12:00 | 12:00 | 12:00 | 12:00 | 1 |
| Plaza & Janés | 26.00 | 17.00 | 21.50 | 43.00 | 2 |
Ahora modificamos la consulta SELECT de antes para que sólo muestre las editoriales que tienen más de un libro y que la media de sus precios sea mayor de 16 euros:
consulta con HAVING
SELECT editorial,
MAX(precio),
MIN(precio),
AVG(precio),
SUM(precio),
COUNT(*)
FROM libros
GROUP BY editorial
HAVING COUNT(*) > 1 AND
AVG(precio) > 16
resultado de la consulta con HAVING
| editorial | precio máximo | precio mínimo | precio medio | suma de precios | cantidad de libros |
|---|---|---|---|---|---|
| McGraw-Hill | 23.50 | 10:50 | 17.00 | 34.00 | 2 |
| Plaza & Janés | 26.00 | 17.00 | 21.50 | 43.00 | 2 |
Cuidado con el uso de HAVING
Las condiciones sobre funciones de agregado NO deben ir en el WHERE porque no pueden aplicarse a cada fila de la tabla, sino a cada grupo de filas. Cuando la base de datos está filtrando las filas, aún no ha agrupado las filas, por lo que no puede aplicar la condición de búsqueda a los grupos. Por eso, si queremos filtrar grupos, debemos usar HAVING.
links a W3Schools
Ejercicios HAVING
Ejercicio 1
Comprueba si hay algún nombre de jugador repetido. Es decir: es necesario mostrar el nombre del jugador y cuántas vueltas aparece pero sólo para aquellos jugadores que tengan el nombre repetido.
Ejercicio 2
Jornadas en las que se han marcado más de 35 goles. Debe aparecer el número de la jornada y la cantidad total de goles correspondiente.
Ejercicio 3
Queremos saber la media de posesión del balón de cada equipo jugando en casa de aquellos equipos en los que su mínima posesión jugando en casa es mayor de 40. Ordenado de mayor a menor posesión. La media de la posesión debe salir sin decimales.
Reglas para procesamiento de consultas de tabla única
Vemos los pasos que sigue el SGBD para procesar una sentencia SELECT:
-
Seleccionará todas las filas de la tabla que se encuentran en la cláusula FROM.
-
Si existe cláusula WHERE, aplicará su condición de búsqueda en cada fila de la tabla. Si para una fila la condición de búsqueda es TRUE, la seleccionará. Pero si es FALSE o NULL, la descartará.
-
Si existe cláusula GROUP BY, las filas seleccionadas anteriormente las clasifica en grupos (donde cada grupo tiene los mismos valores en los campos del GROUP BY).
-
Si hay HAVING, descarta a los grupos anteriores que no cumplen la condición de búsqueda del HAVING.
-
Calcula el valor de cada elemento de la cláusula SELECT para cada fila seleccionada (o bien, para cada grupo si había GROUP BY).
-
Si se especifica SELECT DISTINCT, elimina las filas duplicadas de los resultados que se hubiesen producido.
-
Si existe una cláusula ORDER BY, ordena los resultados de la consulta.
Estas reglas serán ampliadas posteriormente para incluir sentencias SELECT más complejas (con más de una tabla, etc.).
Combinación de resultados de consulta (UNION)
Podemos “unir” dos o más consultas en una sola. Esto es, a partir del conjunto de resultados de una SELECT y del conjunto de resultados de otra SELECT, podemos obtener un único conjunto de resultados.
Para ello, utilizamos la operación UNION. Esta operación combina los resultados de dos o más consultas en un único conjunto de resultados. Las consultas que se combinan deben tener el mismo número de columnas y las columnas deben ser del mismo tipo.
1a consulta: Lista todos los productos que valgan más de 200 €
consulta
SELECT código, nombre
FROM artículos
WHERE precio > 200
resultado de la consulta
| CÓDIGO | NOMBRE |
|---|---|
| ACI | 4100I |
| REI | 2A44L |
| ACI | 4100Z |
| REI | 2A44R |
2a consulta: Lista todos los productos que se hayan vendido por importe de más de 3.000€.
consulta
SELECT DISTINCT artículo, descripción
FROM ventas
WHERE importe > 3000
resultado de la consulta
| ARTÍCULO | DESCRIPCIÓN |
|---|---|
| IMM | 775C |
| REI | 2A44L |
| REI | 2A44R |
Unión: Lista todos los productos que valgan más de 200 € o que se hayan vendido por importe de más de 3.000 €. Es decir: lista los productos que cumplan la primera condición y también aquellos que cumplan la segunda condición.
consulta con UNION
SELECT código, nombre
FROM artículos
WHERE precio > 200
UNION
SELECT DISTINCT artículo, descripción
FROM ventas
WHERE importe > 3000
resultado de la consulta con UNION
| codigo | nombre |
|---|---|
| ACI | 4100I |
| ACI | 4100Z |
| IMM | 775C |
| REI | 2A44L |
| REI | 2A44R |
Algunas consideraciones sobre el UNION:
UNIONquita los resultados duplicados. Si no queremos que los quite es necesario ponerUNION ALL.-
Se pueden poner más de dos
SELECT, separadas por UNION:SELECT * FROM a UNION ( SELECT * FROM b UNION SELECT * FROM c ) -
Las
SELECTdeben tener el mismo número de columnas y ser del mismo tipo. - Los nombres de columnas de las
SELECTno tienen por qué ser igual. Si son distintos, el nombre de las columnas que se mostrarán en el resultado final serán las de la primeraSELECT. - Ninguna de las
SELECTpuede tener la cláusulaORDER BY, pero se puede poner una al final de todo.
Ejercicios UNION
Ejercicio 1
Muestra la quiniela de la primera jornada (equipo casa, equipo fuera, 1x2). Este ejercicio ya se hizo con la función IF. Ahora hazlo sin usar esa función. Y ordenado por el código del equipo que juega en casa.

Ejercicio 2
Cuántos unos, cuántas y cuántos 2 en la primera jornada.

Ejercicio 3
Cuántos unos, cuantas xy cuántos 2 en cada jornada (ordenado por la jornada).

Ejercicio 4
¿Cuántos partidos le queda por jugar a cada equipo en casa y cuántos fuera? Muestra la información ordenada por equipo. Dentro de cada equipo, primero los de casa.

Ejercicio 5
- Cuántos partidos ha ganado/empatado/perdido cada equipo jugando en casa/fuera. Ordenado por equipo. Así (da igual si aparecen primero los ganados o empatados o perdidos):

Verás que no salen las líneas en las que la cantidad de partidos es 0. No te preocupes. Para que salgan habría que usar subconsultas (aún no lo hemos visto).
Resumen de las consultas simples
-
La sentencia
SELECTse utiliza para expresar una consulta SQL. Toda sentenciaSELECTproduce unatablaresultados que contiene una o más columnas y cero o más filas. -
La cláusula
FROMespecifica lastablasque tienen los datos a recuperar en una consulta. -
La cláusula
SELECTespecifica lascolumnasdatos a incluir en los resultados de la consulta, que pueden ser columnas de datos de la BD o columnas calculadas. -
La cláusula
WHEREselecciona lasfilasa incluir en los resultados aplicando una condición de investigación en las filas de la BD. -
Una condición de búsqueda puede seleccionar filas mediante comparación de valores(<, >, = ...), mediante comparación de valor con un rango (
BETWEEN) o un grupo de valores (IN), por correspondencia con un patrón de columna (LIKE) o por comprobación de valores nulos (IS NULL) . -
Las condiciones de investigación simples pueden combinarse mediante
AND,ORyNOTpara formar condiciones de investigación más complejas. -
La cláusula
ORDER BYespecifica que los resultados de la consulta deben ser ordenados en sentido ascendente o descendente, basándose en los valores de una o más columnas. -
La operación
UNIONpuede utilizarse dentro de una sentenciaSELECTpara combinar dos o más conjuntos de resultados y formar un único conjunto.
Ejercicios de la unidad 4.5
Ejercicios de la unidad 4.5