Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Introducción a SQL
Índice
1 Introducción
2 Data Definition Language
3 Data Manipulation Language
4 Select
5 Group by
6 Joins
7 Otros
8 Bibliografı́a
Índice
1 Introducción
2 Data Definition Language
3 Data Manipulation Language
4 Select
5 Group by
6 Joins
7 Otros
8 Bibliografı́a
SQL
Origen
Índice
1 Introducción
2 Data Definition Language
3 Data Manipulation Language
4 Select
5 Group by
6 Joins
7 Otros
8 Bibliografı́a
Comandos
Juegos de caracteres
Comandos DDL
Definición de campos
Tipos de datos
Definición:
nombre_campo tipo marcadores
Tipos:
CHAR(n) Cadenas longitud fija hasta n caracteres.
VARCHAR(n) Cadenas longitud variable hasta n caracteres.
INTEGER, BIGINT, SMALLINT, . . . Enteros.. . .
REAL Número real
DATE Fechas. Están compuestas de: YEAR, MONTH y DAY.
TIME Horas. Están compuestas de HOUR, MINUTE y SECOND.
. . . y muchos más (varı́an según el SGBD).
Marcadores y restricciones
2
Disponible dependiendo del SGBD y su versión
Luis Valencia Cabrera (lvalencia@us.es) Bases de Datos
Introducción a SQL
Introducción DDL DML Select Group by Joins Otros Biblio
3
Disponible dependiendo del SGBD y su versión
Luis Valencia Cabrera (lvalencia@us.es) Bases de Datos
Introducción a SQL
Introducción DDL DML Select Group by Joins Otros Biblio
Comandos ALTER
4
Más información en esta web.
Luis Valencia Cabrera (lvalencia@us.es) Bases de Datos
Introducción a SQL
Introducción DDL DML Select Group by Joins Otros Biblio
Índice
1 Introducción
2 Data Definition Language
3 Data Manipulation Language
4 Select
5 Group by
6 Joins
7 Otros
8 Bibliografı́a
Comandos DML
Modificadores
Operadores lógicos
Operadores de comparación
Funciones de agregado
Índice
1 Introducción
2 Data Definition Language
3 Data Manipulation Language
4 Select
5 Group by
6 Joins
7 Otros
8 Bibliografı́a
Consultas de Selección
Consultas de Selección
Consultas de Selección
Consultas de Selección
Ejemplos
Alias (AS)
Operadores lógicos
SELECT *
FROM Empleados
WHERE (Sueldo > 100 AND Sueldo < 500) OR
(Provincia='Madrid' AND Estado='Casado');
Operador BETWEEN:
SELECT *
FROM Pedidos
WHERE CodPostal BETWEEN 28000 AND 28999;
Combinado con NOT:
SELECT *
FROM Pedidos
WHERE cp NOT BETWEEN 28000 AND 28999;
Luis Valencia Cabrera (lvalencia@us.es) Bases de Datos
Introducción a SQL
Introducción DDL DML Select Group by Joins Otros Biblio
Operador LIKE
Operador IN
Cuantificador EXISTS
Índice
1 Introducción
2 Data Definition Language
3 Data Manipulation Language
4 Select
5 Group by
6 Joins
7 Otros
8 Bibliografı́a
Agrupamiento - GROUP BY
GROUP BY lista campos
combina los registros con valores idénticos para lista campos en un
grupo, para el que se mostrará un único registro. Si se incluye una
función SQL agregada (Sum, Count...) en el SELECT, se obtiene
un valor del cálculo para cada registro (grupo). Su sintaxis es:
SELECT expresiones
FROM tabla
[WHERE lista criterios]
GROUP BY lista campos;
Por ejemplo:
SELECT Id_Familia, Sum(Stock)
FROM Productos
GROUP BY Id_Familia;
Agrupamiento - HAVING
Una vez GROUP BY ha combinado los
registros, HAVING filtra los registros
agrupados que satisfagan las
condiciones del HAVING.
Es similar a WHERE, determina qué
registros se seleccionan. Pero a
diferencia de éste (que afecta a los SELECT Id_Familia, SUM(Stock)
registros originales), HAVING filtra los FROM Productos
registros resultantes de la agrupación, WHERE NombreProducto Like 'BOS%'
según los resultados de los campos GROUP BY Id_Familia
calculados. HAVING SUM(Stock) > 100
Es decir, una vez se han agrupado los
registros utilizando GROUP BY y se han
hecho los cálculos agregados, HAVING
determina cuáles de los nuevos
registros se van a mostrar.
Agrupamiento - AVG
Agrupamiento - Count
COUNT
Algunos ejemplos adicionales
Agrupamiento - Sum
Índice
1 Introducción
2 Data Definition Language
3 Data Manipulation Language
4 Select
5 Group by
6 Joins
7 Otros
8 Bibliografı́a
Producto cartesiano
Joins
Joins
Joins
Reflexividad
Índice
1 Introducción
2 Data Definition Language
3 Data Manipulation Language
4 Select
5 Group by
6 Joins
7 Otros
8 Bibliografı́a
Subconsultas
ANY
Formato general:
Operador ANY Subconsulta
ANY se usa con un operador de comparación, y el resultado de la
misma se evalúa como Verdadero si la comparación resulta cierta
para algún valor devuelto por la subconsulta.
Por ejemplo:
SELECT s1
FROM t1
WHERE s1 > ANY (SELECT s1 FROM t2);
COALESCE
SELECT Nombre,
COALESCE(FijoCasa, FijoTrabajo, Móvil) Telefono
FROM Clientes;
Índice
1 Introducción
2 Data Definition Language
3 Data Manipulation Language
4 Select
5 Group by
6 Joins
7 Otros
8 Bibliografı́a
Bibliografı́a I
Mercedes Marqués
Apuntes de Bases de Datos.
Universidad Jaume I en Castellón (2011)
ISBN: 978-84-693-0146-3
Bibliografı́a II
Bibliografı́a III
Consultas sencillas
Devolver todos los campos de una tabla (SELECT *)
SELECT *
FROM CLIENTES
Con el * indicamos que queremos devolver todos los campos. Si CLIENTES dispone de los
campos idCliente, nombre y descripcion, lo anterior sería equivalente a:
Operadores relacionales
Al margen del signo de igualdad empleado anteriormente, se pueden usar n las condiciones
simples de las consultas los operadores relacionales habituales, devolviendo siempre un valor
booleano (lógico):
Operador Significado
< Menor que
> Mayor que
<> Distinto de
<= Menor ó Igual que
>= Mayor ó Igual que
= Igual que
SELECT nombre
FROM CLIENTES
WHERE edad <= 32
LIKE: empleado para comparar patrones de texto pudiendo incluir comodines como los
siguientes:
Comodín Descripción
% Sustituto para cero o más caracteres.
_ Sustituto para exactamente un carácter
[lista caracteres] Cualquier carácter de la lista
[^lista caracteres] Cualquier carácter que no esté en la lista
[!lista caracteres] Cualquier carácter que no esté en la lista
IN: empleado para comparar con una lista de valores fijados de modo que devuelva True si el
campo indicado pertenece a la lista.
SELECT num, calle, direccion
FROM DIRECCION
WHERE ciudad IN (‘Sevilla’, ’Córdoba’, ‘Huelva’, ‘Cádiz’)
Operador Significado
AND Y lógico
OR O lógico
NOT Negación lógica
SELECT *
FROM DIRECCION
WHERE ciudad = ‘Sevilla’ AND cp = 41009 OR ciudad = ‘Córdoba’ AND NOT cp = 14010
Devuelve los registros pertenecientes a direcciones que tengan el código postal 41009 de
Sevilla o bien que no tengan el 14010 de Córdoba. La mayor precedencia la adopta el operador
NOT sobre la condición cp = 14010; a continuación los AND se aplican sobre ciudad = ‘Sevilla’
AND cp = 41009 y ciudad = ‘Córdoba’ AND NOT cp = 14010; por último se aplica el OR sobre la
fórmula completa. La misma consulta se puede expresar de forma más clara con paréntesis:
SELECT *
FROM DIRECCION
WHERE (ciudad = ‘Sevilla’ AND cp = 41009) OR
(ciudad = ‘Córdoba’ AND (NOT cp = 14010))
O bien si el NOT nos parece más evidente, podemos excluir el paréntesis interior, a nuestra
gusto siempre conservando el significado que queríamos dar la operación.
Ordenación
Ordenar según criterios (ORDER BY)
Podemos ordenar los registros devueltos por una consulta por el campo o campos que
estimemos oportunos:
SELECT *
FROM CIUDAD
ORDER BY provincia ASC, numhabitantes DESC
Esta consulta devolvería todas las ciudades ordenadas por provincia en orden ascendente, y
dentro de los de la misma provincia ordenaría las ciudades por orden descendente del número
de habitantes. Si no indicamos ASC ni DESC, el comportamiento por defecto será el orden
ascendente (ASC).
Devolución de expresiones
Asignación de un alias a un dato devuelto (AS)
SELECT idCliente AS id, nombre AS cliente, descripcion AS desc
FROM CLIENTES
Ahora bien, podemos querer obtener información que no proviene de un registro individual
sino de la agrupación de información, como es el caso de contar el número de líneas de
pedido, sumar el precio de todas las líneas por cada pedido, etc. Para ello, debemos emplear
funciones agregadas y en la mayoría de los casos agrupar por algún campo.
Si por el contrario deseamos obtener el total de líneas por pedido, debemos indicar que
agrupe por idPedido, lo que contará todos los registros con el mismo idPedido y calculará su
cuenta:
SELECT idPedido, COUNT(*)
FROM LINEAPEDIDO
GROUP BY idPedido
Lo mismo se puede aplicar a otras funciones como la suma, indicando en ese caso aparte de la
agrupación el campo que queremos sumar:
SELECT idPedido, SUM(precioLinea)
FROM LINEAPEDIDO
GROUP BY idPedido
¿Y si queremos hallar la media de los precios por cada pedido? En ese caso necesitamos de
nuevo agrupar (GROUP BY) por pedido.
SELECT idPedido, AVG(precioLinea)
FROM LINEAPEDIDO
GROUP BY idPedido
Igualmente, podríamos aplicar un redondeo (ROUND) sobre la media, para dejar 4 decimales, y
aplicarle un alias (AS) para el nombre del dato de salida.
SELECT idPedido, ROUND(AVG(precioLinea),4) AS media
FROM LINEAPEDIDO
GROUP BY idPedido
O podríamos establecer una condición sobre el dato agrupado (HAVING), de forma que
solamente se muestren las medias menores o iguales que 10. Existe una gran cantidad de
funciones de agregación definidas en SQL, pero hay que tener precaución porque pueden
diferir de un SGBD a otro.
Para practicar un poco con las más comunes es muy recomendable este tutorial interactivo. En
MySQL tendríamos las que aparecen en este enlace. Este es el desglose completo de las
funciones de agregación estándar:
Function Usage
Computes the average value of a column given
AVG(expression)
by expression.
VENTA
CLIENTE
podemos obtener una consulta que obtenga datos del cliente y de la venta. Por ejemplo,
nombre, apellidos, codcoche y color, mediante una consulta del tipo:
INNER JOIN
Con la notación explícita también podemos expresar un CROSS JOIN como se indicó en el caso
explícito:
Nota: aunque lo más frecuente es que la condición del JOIN sea en términos de igualdad entre
las claves, también se podrían establecer condiciones empleando otros operadores
relacionales (operadores para comparar dos valores, devolviendo un resultado booleano, es
decir, cierto o falso):
El resultado de esta operación siempre contiene todos los registros de la relación izquierda
(primera tabla que indicamos), y aquellos de la tabla derecha que cumplen la condición
establecida. Para el resto aparecerá en los campos correspondientes a dicha tabla un NULL.
SELECT nombreCliente, idPedido, fechaPedido
FROM CLIENTE LEFT JOIN PEDIDO
ON cliente.idCliente = pedido.idCliente
Esta consulta devolverá todos los clientes con sus pedidos, y un registro por cada cliente que
no tenga pedidos.
RIGHT JOIN
El RIGHT JOIN es análogo al LEFT JOIN, pero devolviendo todos los registros de la relación
derecha (segunda tabla que aparece), y únicamente aquellos de la tabla izquierda que cumplen
la condición del JOIN. El resultado de esta operación siempre contiene todos los registros de la
relación derecha (segunda tabla que indicamos), de modo que en aquellos sin equivalente en
la parte izquierda tendrán en los campos correspondientes a dicha tabla un NULL.
SELECT nombreCliente, idPedido, fechaPedido
FROM CLIENTE RIGHT JOIN PEDIDO
ON cliente.idCliente = pedido.idCliente
Asumiendo que pudiéramos tener en la base de datos pedidos sin cliente asociado, esta
consulta devolverá todos los pedidos con sus clientes, y en caso de que el cliente no aparezca
el nombreCliente sería NULL.
Como se puede ver, esta consulta es equivalente a mostrar tanto los registros devueltos por el
LEFT como por el RIGHT JOIN, eliminando los repetidos (aquellos registros que cumplan la
condición del JOIN, que serían devueltos por ambas consultas).
El hecho de unir los registros de las consultas de LEFT y JOIN, ambas devolviendo los mismos
tipos de campos (EMPLEADO.nombre, EMPLEADO.apellidos, EMPRESA.nombre) puede ser
expresado en SQL a través de la cláusula UNION:
Para devolver los registros de la consulta anterior excluyendo los repetidos haríamos:
SELECT DISTINCTROW
FROM (SELECT EMPLEADO.nombre, EMPLEADO.apellidos, EMPRESA.nombre
FROM EMPLEADO
LEFT JOIN EMPRESA
ON EMPLEADO.empresa = EMPRESA.cif
UNION
SELECT EMPLEADO.nombre, EMPLEADO.apellidos, EMPRESA.nombre
FROM EMPLEADO
RIGHT JOIN EMPRESA
ON EMPLEADO.empresa = EMPRESA.cif)
Ahora bien, podríamos haber evitado los duplicados mediante una solución más ingeniosa,
devolviendo en una de las dos consultas (LEFT o RIGHT) solamente los registros de una de las
partes, excluyendo así los que cumplen la condición del JOIN, que serán devueltos por la otra:
Algunos ejercicios adicionales sobre JOIN pueden encontrarse en este tutorial y los primeros 4
apartados de este otro (los restantes ejercicios emplean conceptos que no hemos visto),
ambos en SQLZOO.
Consultas anidadas
A veces se han de utilizar en una consulta los resultados de otra consulta, llamada subconsulta
o consulta anidada. Podemos ver muchos ejemplos de ello aquí. Veamos que existen diversas
variantes:
Empleando IN
Obtener el identificador de los clientes que han comprado algún coche a un concesionario de
Madrid.
SELECT DISTINCT cifcl
FROM VENTA
WHERE cifc IN (SELECT cifc
FROM CONCESIONARIO
WHERE ciudad = 'Madrid')
Obtener el código de coche de los coches vendidos por algún concesionario de Madrid.
SELECT DISTINCT codcoche
FROM VENTA
WHERE cifc IN (SELECT cifc
FROM CONCESIONARIO
WHERE ciudad = 'Madrid')
Obtener el nombre y el modelo de los coches vendidos por algún concesionario de Barcelona.
SELECT nombre, modelo
FROM COCHE
WHERE codcoche IN (SELECT codcoche
FROM VENTA
WHERE cifc IN (SELECT cifc
FROM CONCESIONARIO
WHERE ciudad = 'Barcelona'))
Empleando ANY
Obtener el nombre y apellidos de los clientes cuyo identificador de cliente es mayor que el de
alguno de los de Madrid, y cuyo nombre empieza por a.
SELECT nombre, apellidos
FROM CLIENTE
WHERE cifcl > ANY
(SELECT cifcl
FROM CLIENTE
WHERE ciudad = 'Madrid')
AND nombre LIKE 'A%'
Empleando EXISTS
Obtener los identificadores de los clientes que sólo han comprado coches al concesionario 1.
SELECT cifcl
FROM VENTA va
WHERE NOT EXISTS (SELECT *
FROM VENTA vb
WHERE cifc <> 1
AND va.cifcl = vb.cifcl)
Obtener los identificadores de los clientes que han comprado coches al concesionario 1 y a
algún otro.
SELECT cifcl
FROM VENTA va
WHERE cifc = 1
AND EXISTS (SELECT *
FROM VENTA vb
WHERE cifc <> 1
AND va.cifcl = vb.cifcl)
Resumen sentencias SQL
Lenguaje de definición de datos (DDL):
Definición de tablas relacionales (CREATE TABLE): CREATE TABLE nombre_tabla (
atributo_1 dominio_1 [NOT NULL] [UNIQUE] [PRIMARY KEY] [DEFAULT valor],
..., atributo_n dominio_n [NOT NULL] [UNIQUE] [PRIMARY KEY]
[DEFAULT valor],
[PRIMARY KEY (atributo, ...)],
[FOREIGN KEY (atributodemitabla_i,...,atributomitabla_j)
REFERENCES otra_tabla (atributootratabla_i,...atributo_otratabla_j)]*
)
Tipos de datos
Pese a la pretensión de SQL como estándar, que define una serie de tipos, que podemos
encontrar en diversos recursos: W3Schools, SQL for dummies, etc. La realidad es que
dependiendo del SGBD que empleemos se dan cambios sustanciales: SQLite, Access, MySQL,
SQL Server, PostgreSQL, Oracle, etc. Por ejemplo, en SQLite solemos almacenar las fechas
como TEXT, de modo que trabajemos con ellas con instrucciones del tipo:
Algunas referencias:
Problema 1.
Consideremos que tenemos una base de datos con las siguientes tablas
PROVEEDORES ENVIOS
IDP PNOMBRE CATEGORIA CIUDAD IDP IDT IDC CANT
P1 CARLOS 20 SEVILLA P1 T1 C1 200
P2 JUAN 10 MADRID P1 T4 C1 700
P3 JOSE 30 SEVILLA P2 T1 C3 400
P4 INMA 20 SEVILLA P2 T2 C3 200
P5 EVA 30 CACERES P2 T3 C3 200
P2 T4 C3 500
COMPONENTES P2 T5 C3 600
IDC CNOMBRE COLOR PESO CIUDAD P2 T6 C3 400
C1 X3A ROJO 12 SEVILLA P2 T7 C3 800
C2 B85 VERDE 17 MADRID P2 T2 C5 100
C3 C4B AZUL 17 MALAGA P3 T1 C3 200
C4 C4B ROJO 14 SEVILLA P3 T2 C4 500
C5 VT8 AZUL 12 MADRID P4 T3 C6 300
C6 C30 ROJO 19 SEVILLA P4 T7 C6 300
P5 T2 C2 200
ARTICULOS P5 T4 C2 100
IDT TNOMBRE CIUDAD P5 T4 C5 500
T1 CLASIFICADORA MADRID P5 T7 C5 100
T2 PERFORADORA MALAGA P5 T2 C6 200
T3 LECTORA CACERES P5 T4 C1 100
T4 CONSOLA CACERES P5 T4 C3 200
T5 MEZCLADORA SEVILLA P5 T4 C4 800
T6 TERMINAL BARCELONA P5 T5 C5 400
T7 CINTA SEVILLA P5 T4 C6 500
La tabla PROVEEDORES representa los datos de proveedores de componentes para
la fabricación de artı́culos y su ciudad de residencia. La tabla COMPONENTES indica
la información de piezas utilizadas en la fabricación de diferentes artı́culos, indicándose el
lugar de fabricación de dichos componentes. La tabla ARTICULOSproporciona informa-
ción sobre los diferentes artı́culos que se fabrican y el lugar de montaje del mismo. Por
últimos, la tabla ENVIOS proporciona información sobre los suministros realizados por
los diferentes proveedores de determinadas cantidades de componentes asignadas para la
elaboración del artı́culo correspondiente.
La información relativa a estas tablas la puedes encontrar en el fichero
ejemploComponentes.sql. Puedes importarlo en phpMyAdmin o abrirlo desde MySQL-
Workbench y ejecutarlo.
Se pide:
Obtenga, para cada uno de los siguientes apartados, una sentencia SQL que permita
obtener la información pedida (pruébelo en MySQL):
1
1. Obtener todos los detalles de todos los artı́culos de CACERES.
2. Obtener todos los valores (distintos) de IDP para los proveedores que abastecen el
artı́culo T1;
5. Obtener los valores de IDP para los proveedores que suministran para el artı́culo
T1 el componente C1.
6. Obtener los valores de TNOMBRE en orden alfabético para los artı́culos abastecidos
por el proveedor P1.
7. Obtener los valores de IDC para los componentes suministrados para cualquier
artı́culo de MADRID.
8. Obtener todos los valores de IDC de los componentes tales que ningún otro compo-
nente tenga un valor de peso inferior.
9. Obtener los valores de IDP para los proveedores que suministren los artı́culos T1 y
T2. Recuerda que Mysql no tiene el operador INTERSECT.
10. Obtener los valores de IDP para los proveedores que suministran para un artı́culo
de SEVILLA o MADRID un componente ROJO.
11. Obtener, mediante subconsultas (SELECT anidados), los valores de IDC para los
componentes suministrados para algún artı́culo de SEVILLA por un proveedor de
SEVILLA.
12. Obtener los valores de IDT distintos para los artı́culos que usan al menos un com-
ponente que se puede obtener con el proveedor P1.
13. Obtener todas las ternas (CIUDAD1, IDC, CIUDAD2) tales que un proveedor de
la CIUDAD1 suministre el componente especificado para un artı́culo montado en la
CIUDAD2.
14. Repetir el ejercicio anterior pero sin recuperar las ternas en los que los dos valores
de ciudad sean los mismos.
16. Para cada artı́culo y componente suministrado obtener los valores de IDC, IDT y
la cantidad total correspondiente.
17. Obtener los valores de IDT de los artı́culos abastecidos al menos por un proveedor
que no sea de MADRID y que no sea de la misma ciudad en la que se monta el
artı́culo.
2
18. Obtener los valores de IDP para los proveedores que suministran al menos un com-
ponente suministrado al menos por un proveedor que suministra al menos un com-
ponente ROJO.
19. Obtener los identificadores de artı́culos IDT para los que se ha suministrado algún
componente del que se haya suministrado una cantidad media superior a 500 artı́cu-
los.
20. Seleccionar los identificadores de proveedores que hayan realizado algún envı́o con
Cantidad mayor que la media de los envı́os realizados para el componente a que
corresponda dicho envı́o.
22. Seleccionar todos los datos de los envı́os realizados de componentes cuyo color no
sea ’ROJO’.
23. Seleccionar los identificadores de componentes que se suministren para los artı́culos
’T1’ y ’T2’.
26. Seleccionar los datos de envı́o y nombre de ciudad de aquellos envı́os que cumplan
que el artı́culo, proveedor y componente son de la misma ciudad.
27. Seleccionar los nombres de los componentes que son suministrados en una cantidad
total superior a 500.
29. Seleccionar los identificadores de artı́culos para los cuales todos sus componentes se
fabrican en una misma ciudad.
30. Seleccionar los identificadores de artı́culos para los que se provean envı́os de todos
los componentes existentes en la base de datos.
31. Seleccionar los códigos de proveedor y artı́culo que suministran al menos dos com-
ponentes de color ’ROJO’.
3
Problema 2.
Consideremos una base de datos con las siguientes relaciones:
4
8. Obtener todas las parejas de identificadores de clientes y marcas que no sean de la
misma ciudad.
9. Obtener los códigos de los coches distribuidos por algún concesionario de Barcelona.
11. Obtener los códigos de los coches adquiridos por un cliente de Madrid en un conce-
sionario de Madrid.
13. Obtener los códigos de los coches comprados en un concesionario de distinta ciudad
que el cliente que lo compra.
14. Obtener todas las parejas de nombres de marcas que sean de la misma ciudad.
15. Obtener las parejas de modelos de coches cuyo nombre es el mismo y cuya marca
es de Bilbao.
16. Obtener todos los códigos de los coches cuyo nombre empiece por c.
17. Obtener todos los códigos de los coches cuyo nombre no contiene ninguna a. R.
Obtener el número total de nombres de marcas de coche que son de Madrid.
18. Obtener la media de la cantidad de coches que distribuyen todos los concesionarios.
19. Obtener el identificador de cliente con la numeración más alta de todos los clientes
de Madrid.
20. Obtener el identificador de cliente con numeración más baja de los que han comprado
un coche blanco.
21. Obtener el identificador de los concesionarios cuyo número de coches en stock (coches
que distribuyen) no es nulo.
22. Obtener el identificador y nombre de las marcas de coches cuya segunda letra del
nombre de la ciudad de origen sea una i.
23. Obtener el identificador de los clientes que han comprado algún coche a un conce-
sionario de Madrid.
25. Obtener el código de los coches vendidos por algún concesionario de Madrid. Rea-
lizarlo de dos formas: sin y con exists.
26. Obtener el nombre y modelo de los coches vendidos por algún concesionario de
Barcelona.
27. Obtener todos los nombre de los clientes que hayan adquirido algún coche del con-
cesionario dcar.
28. Obtener el nombre y apellido de los clientes que han adquirido un coche modelo gti
de color blanco.
5
29. Obtener el nombre y apellido de los clientes que han adquirido un automóvil a un
concesionario de Madrid que posea actualmente coches en stock del modelo gti.
30. Obtener el nombre y apellido de los clientes con identificador menor que el del cliente
Juan Martı́n.
31. Obtener el nombre y apellido de los clientes cuyo identificador es menor que el de
los clientes de Barcelona.
32. Obtener el nombre y apellido de los clientes cuyo nombre empieza por a y cuyo
identificador es mayor que el de todos los clientes de Madrid.
33. Obtener el nombre y apellido de los clientes cuyo nombre empieza por a y cuyo
identificador es mayor que el de alguno de los clientes de Madrid.
34. Obtener el nombre y apellido de los clientes cuyo nombre empieza por A y: cuyo
identificador es mayor que el de alguno de los clientes de Madrid, o menor que el de
todos los de Valencia.
35. Obtener el nombre y apellido de los clientes que han comprado como mı́nimo un
coche blanco y otro rojo.
36. Obtener el identificador de los clientes cuya ciudad sea la última de la lista alfabética
de las ciudades donde hay concesionarios.
37. Obtener la media de los automóviles que cada concesionario tiene actualmente en
stock (es decir, los que distribuye).
38. Obtener el identificador del concesionario que no sea de Madrid cuya media de
vehı́culos en stock sea la más alta de todas las medias.
39. Obtener usando exists el identificador de los clientes que hayan adquirido por lo me-
nos alguno de los coches que ha sido vendido por el concesionario cuyo identificador
es 1.
40. Obtener los identificadores de los clientes que sólo han comprado coches al conce-
sionario 1.
41. Obtener los nombres de los clientes que no han comprado ningún coche rojo a ningún
concesionario de Madrid.
42. Obtener el nombre de los clientes que sólo han comprado en el concesionario 1.
43. Obtener el código de coche de aquellos automóviles comprados por todos los clientes
de Madrid.
44. Obtener el código de coche de aquellos automóviles de color rojo y de modelo gti
que han sido comprados por todos los clientes cuyo apellido comienza por g.
45. Obtener el identificador de los clientes que han adquirido por lo menos los mismos
automóviles que el cliente Luis Garcı́a.
46. Obtener el identificador de los concesionarios que han vendido el mismo coche a
todos los clientes.