SQL Complex Queries Approach
SQL Complex Queries Approach
Some methodological
considerations to solve complex
SQL queries
1
Types of Queries
Example: List the name of the mountain passes (‘puertos’) with an altitude which is greater
than the mean of the altitude of all the mountain passes of category 2.
SELECT nompuerto FROM Puerto
WHERE altura > (SELECT AVG(altura) FROM Puerto WHERE categoría = 2 );
Example: List the name of the mountain passes and the racers (‘ciclistas’) which have won
them, such that the pass has the greatest slope (‘pendiente’).
Solution with a MAX (aggregated function).
SELECT P.nompuerto, C.nombre FROM Puerto P, Ciclista C
WHERE P.dorsal = C.dorsal AND
P.pendiente = (SELECT MAX(P1.pendiente) FROM Puerto P1 );
Solution with a >= ALL.
SELECT P.nompuerto, C.nombre FROM Puerto P, Ciclista C
WHERE P.dorsal = C.dorsal AND
P.pendiente >= ALL (SELECT P1.pendiente FROM Puerto P1 ); 4
QUERIES WITH NEGATION OF AN EXISTENTIAL PROPERTY.
Example: List el name de the racer which has NOT won any stage.
The negation doesn’t affect a simple attribute, but affects the existence or not of row in
the “etapa” table for that racer. In this case, then, we have the negation of an existential
property (to win stages), i.e., the property is “that there exists a stage which has been won
by the racer”. Its negation is “that there does not exist a stage which has been won by the
racer”. In SQL…
Solution with subquery with NOT EXISTS.
SELECT C.nombre FROM Ciclista C
WHERE NOT EXISTS (SELECT * FROM Etapa E
WHERE E.dorsal = C.dorsal);
Solution with subquery with NOT IN.
SELECT name FROM Ciclista
WHERE dorsal NOT IN (SELECT dorsal FROM Etapa);
But the following one is COMPLETELY WRONG:
SELECT C.nombre FROM Ciclista C, Etapa E
5
WHERE E.dorsal <> C.dorsal;
QUERIES WITH UNIVERSAL QUANTIFICATION
(in the question in natural language we may frequently find the words “all/every” or
“only”).
Solution: It’s necessary to use subqueries with a NOT IN or a NOT EXISTS
and, inside the subquery, another negation, which can be a simple non-
existential negation (<>) or an existential negation (NOT EXISTS o NOT IN).
Example: List the name of the racer (if there is one) which has won all the stages with
more than 200 km.
Solution: we transform the query to “undo” the word “all”, with the following schema:
∀x p ⇒ ¬∃x¬p NOT EXISTS ( …2nd negation….)
This converts the query into “List the name of the racer such that there does not exist a
stage with more than 200 km. which he has not won” which we can now express in SQL.
SELECT name FROM Ciclista C
WHERE NOT EXISTS (SELECT * FROM Etapa E
WHERE km > 200 AND C.dorsal <> E.dorsal );
It is very important to know which part is negated. Here, the condition “km > 200” must
remain unaltered, but the condition “C.dorsal = E.dorsal” must be negated, because we
want to say that he has not won the stage. 6
QUERIES WITH UNIVERSAL QUANTIFICATION (ADD-ONS)
Example with two not exists: “List the name of the racers which have worn all the
jerseys (maillots)”.
Solution: we transform it into “List the name of the racers such that there is no jersey
which hasn’t been worn by them”. Or in order to see it clearer with two negations of the
two existential quantification, we can express it as:
“List the name of the racers such that there does not exist a jersey for which there does
not exist a row in “llevar” which connects the racer and the ciclist”
8
QUERIES WITH UNIVERSAL QUANTIFICATION
Example with “ONLY”: List the colour of the jerseys which have only been worn by
racers of the same team.
Solution: these queries have the same schema as the universal quantification; generally,
these queries can be translated into expressions like “that there is one and there is no
other or different”.
In this case, we transform the previous query into “List the colour of the jerseys which
have been worn by a racer of one team and which have not been worn by a racer of a
different team”
9
QUERIES WITH UNIVERSAL QUANTIFICATION
“List the name of the racers which have worn all the jerseys (maillots)”.
Even though we have the “FOR ALL” operator we need some transformation
Solution: we transform it into “List the name of the racers such that for every jersey it
has been worn by them”.
10
QUERIES WITH DIRECT AND AGGREGATED VALUES IN THE
SELECT OR WHICH CAN BE EXPRESSED AS “FOR EACH X LIST …”.
Example: List the name of each team and the average age of the racers of the team:
SELECT nomeq, AVG(edad) FROM Ciclista
GROUP BY nomeq;
1) List the stage number and the start city of those stages which have
no mountain passes.
• Consulta el número de las etapas y la ciudad de salida de aquellas etapas que no
tengan puertos de montaña.
13
MORE EXAMPLES FOR THE ‘CICLISMO’ SCHEMA
2) List the name of the start and arrival cities of the stage with the
mountain pass with greatest slope.
•Consulta el nombre de la ciudad de salida y de llegada de la etapa donde está el
puerto con mayor pendiente.
SELECT name
FROM ciclista c
WHERE edad = ( SELECT MIN(edad) FROM ciclista );
15
4) List the name of the racers which have won all the mountain passes of one stage
and which have also won that stage. ( Exercise 17 )
•Consulta el nombre de los ciclistas que han ganado todos los puertos de una etapa y
además han ganado esa misma etapa. ( Ej. 17 boletín )
17
6) List the name of the racers which belong to a team which has more
than 5 racers, also showing the number of stages won by each.
•Consulta el nombre de los ciclistas que pertenezcan a un equipo que tenga más de
cinco corredores indicando el número de etapas ganadas por cada uno.
18
7) List the name of the teams which have the maximum average age of
all the teams.
•Consulta el nombre de los equipos que tengan la media de edad máxima de todos los
equipos.
20