You are on page 1of 44

SQL: Consultas Avanzadas

Bases de Datos
Resumen: Consultas Básicas

SELECT [DISTINCT] <attribute list>


FROM <table list>
[WHERE <condition on the tables>]
[GROUP BY <grouping attributes>]
[HAVING <group condition>]
[ORDER BY <attribute list> ASC | DESC]
[LIMIT <number of tuples>]
Contenido

1. Relaciones Temporales

2. Clausula WITH

3. Tabla Temporary

4. Operaciones Join

5. Operaciones SQL de conjuntos

6. Técnicas de formulación de consultas


Consulta SQL: Relación Temporal

• Resultado de una consulta SELECT (que existe


temporalmente) y que ayuda a formular otra consulta

• Sintaxis:
SELECT <attributes>
FROM R1, R2, (SELECT … ) <alias>, …, RN WHERE
<condition>;

• Se debe utilizar siempre un alias para denotar la relación


que resulta del comando SELECT
Ejemplo: Relación Temporal

Buscar el nombre, el apellido y el salario de los empleados


masculinos con salario > 50K

SELECT *
FROM (SELECT fname, lname, salary
FROM employee
WHERE sex = ‘M’) r1
WHERE r1.salary > 50000;
Detalles de la Relación Temporal

• Se pueden usar múltiples relaciones temporales

• No se puede usar una relación temporal para crear otra


relación temporal

 Ejemplo de uso incorrecto:


SELECT …
FROM …, (SELECT …) r1,
(SELECT … FROM r1 …) r2, ...
WHERE …;
Consulta SQL: WITH
• El estándar SQL-99 introdujo la clausula WITH para ayudar
a refinar el resultado de una consulta (otra forma de lograr
una relación temporal)

• Sintaxis:
WITH <alias> AS (SELECT …)[,
<alias2> AS (SELECT …)]
SELECT <query>;

• Se puede usar para hacer un "refinamiento" en una


consulta
 La consultas posteriores en la clausula WITH pueden
usar los resultados de la consulta anterior
Ejemplo: WITH
Buscar toda la información de las personas a cargo de
John Smith

WITH r1 as ( SELECT *
FROM employee
WHERE fname = ‘John’
AND lname = ‘Smith’)
SELECT *

FROM dependent

WHERE essn IN (SELECT ssn from r1);
Detalles de la clausula WITH

• Algunos proveedores no soportan WITH (por ejemplo,


MySQL soporta WITH a partir de la versión 8.0)

• Alternativas:

• Relación TEMPORAL

• Tabla TEMPORARY

• View (como veremos más adelante)


Consulta SQL: Tabla Temporary
• Útil para almacenar y procesar resultados intermedios
usando los mismos comandos, select, update, y join que en
las tablas típicas.

• Las tablas temporarias se eliminan cuando el cliente cierra


sesión

• Cada proveedor tiene una sintaxis diferente para crear tablas


temporarias.
Sintaxis en MySQL: Tabla Temporary
• Sintaxis:
CREATE TEMPORARY TABLE tbl_name …

• Ejemplo usando un comando select


CREATE TEMPORARY TABLE top5Emp AS
(SELECT * FROM employee ORDER BY
salary DESC LIMIT 5 );

• Ejemplo con tabla vacía:


CREATE TEMPORARY TABLE empSum
( ssn CHAR(9) NO NULL,
dependentNo INT DEFAULT 0,
salary DECIMAL(7,2));
Consulta SQL: Operaciones JOIN

• El estándar SQL-99 agregó varias operaciones Join:

• INNER JOIN (normal join)

• LEFT JOIN (left outer join)

• RIGHT JOIN (right outer join)

• FULL JOIN (outer join)


Consulta SQL: Operaciones JOIN

• Cada operación produce una relación

• La operación solo puede aparecer en:

 la clausula FROM de la consulta SELECT

 la clausula WHERE de la consulta SELECT con un


operador que usa una subconsulta
Consulta SQL: [INNER] JOIN
• Calcula el (inner) join entre las tablas r1 y r2 con una
condición join dada

• Sintaxis:
r1 JOIN r2 ON <join-condition>;
o
r1 INNER JOIN r2 ON <join-condition>;

• La operación JOIN hace que la consulta SQL se


parezca bastante a la consulta en el AR

• Se puede hacer join entre mas de 2 relaciones


Ejemplo: INNER JOIN
Buscar el nombre y el apellido de los empleados que
trabajan en el departamento ‘Research’

Consulta en el AR:
⇡fname,lname ( dname=‘Research’ )(EMPLOYEE ./dno=dnumber D
EPARTMENT)

Consulta SQL:

SELECT fname, lname


FROM (employee JOIN department ON dno = dnumber)
WHERE dname = ‘Research’;
Consulta SQL: OUTER JOIN
• Calcula el outer join entre las tablas r1 y r2 con una
condición join dada - Ver los slides del AR para detalles
sobre las diferencias entre left, right, y full outer joins

• Sintaxis:
r1 LEFT | RIGHT| FULL [OUTER] JOIN r2 on <join condition>;

• Resulta en valores nulos (NULL) para los atributos donde


no ocurren coincidencia (matching) de las tuplas
Consulta SQL: NATURAL JOIN

• Calcula el natural join entre dos o más tablas basados en


los atributos con los mismos nombres. El atributo en
común aparece solo una vez en el resultado

• Sintaxis:
r1 NATURAL JOIN r2;

• Ejemplo:
SELECT *
FROM works_on NATURAL JOIN dependent;
Consulta SQL: CROSS JOIN

• El Cross Join es igual que el Producto Cartesiano

• Sintaxis:
r1 CROSS JOIN r2;

• Ejemplo:
SELECT ssn, fname, lname, dno, dnumber, dname
FROM employee CROSS JOIN dependent;
SQL: Join Implicito vs Join Explicito

• ¿Cual es la diferencia?

• SELECT * SELECT *
FROM table1 a INNER vs FROM table1 a, table2 b
JOIN table2 b ON a.id WHERE a.id = b.id;
= b.id;

• (inner) join implicito vs join implicito

• En algunos sistemas, las consultas explicitas se


optimizan mejor para cantidades grandes de registros
SQL: Operaciones de Conjuntos
No todas las operaciones sobre conjuntos se han incorporado en
los proveedores de Bases de Datos:
 CARTESIAN PRODUCT: integrado dentro del comando SELECT

 UNION: incorporado en la mayoría de los proveedores debido a


que es muy fácil combinar 2 conjuntos (complejidad O(n))

 INTERSECT: incorporado en pocos proveedores debido a que


es difícil intersecar 2 conjuntos (complejidad O(N log N)),
ejemplos: Oracle 10g, SQL Server

 MINUS: casi ningún proveedor incorpora esta operación (tan


costoso como INTERSECT), ej. Oracle 10g
SQL: Operaciones de Conjuntos (2)
• La operaciones de conjuntos producen como resultado
conjuntos de tuplas -> las tuplas duplicadas son
eliminadas del resultado

• Las operaciones de conjuntos solo se aplican a las


relaciones compatibles con la unión: las relaciones
deben tener los mismos atributos y los atributos deben
estar en el mismo orden.

• La operación DIVISION de conjuntos no es parte del


estándar SQL

• MySQL solo implementa la operación UNION


Ejemplo: UNION

Buscar el nombre de los proyectos donde trabajan


‘Smith’ o ‘Borg’

(SELECT pname
FROM project, works_on, employee
WHERE pnumber = pno
AND essn = ssn AND lname = ‘Smith’)
UNION
(SELECT pname
FROM project, works_on, employee
WHERE pnumber = pno
AND essn = ssn AND lname = ‘Borg’);
Ejemplo: UNION (2)
Listar todos los nombres de proyectos que involucren a un
empleado cuyo apellido es 'Smith', ya sea como trabajador o
como gerente del departamento que controla el proyecto.

(SELECT pname
FROM project, department, employee
WHERE dnum = dnumber AND mgrssn = ssn
AND lname = ‘Smith’)
UNION
(SELECT pname
FROM project, works_on, employee
WHERE pnumber = pno AND essn = ssn
AND lname = ‘Smith’);
SQL: Más allá de la Union

• ¿Puedo hacer consultas (sql) que usen intersección,


diferencia o división?

• ¿Cuáles son las técnicas para satisfacer a estas


consultas?

• Resp: Existen técnicas de formulación de consultas


(QFT, por sus siglas en ingles) que se pueden seguir
para resolver esta deficiencias
QFT: INTERSECT
¿Cómo calcular la intersección de dos conjuntos cuando el
proveedor no incorpora la operación INTERSECT (por
ejemplo, MySQL)?

x IN (set1 INTERSECT set2)

(x IN set1) AND (x IN set2)


Ejemplo: INTERSECT
Buscar el nombre y el apellido de los empleados que trabajan en algún
proyecto controlado por el departamento ‘Research’ y también en algún
proyecto controlado por el departamento ‘Administration’

SELECT fname, lname


FROM employee
WHERE ssn IN ( SELECT essn
FROM works_on, project, department

WHERE pno = pnumber

AND dnum = dnumber AND dname = ‘Research’)
AND ssn IN ( SELECT essn
FROM works_on, project, department

WHERE pno = pnumber AND dnum = dnumber

AND dname = ‘Administration’);
QFT: DIFFERENCE

¿Cómo calcular la diferencia de dos conjuntos cuando


el proveedor no admite la operación MINUS?

x IN (set1 - set2)

(x IN set1) AND (x NOT IN set2)


Ejemplo: DIFFERENCE
Buscar el SSN de los empleados en el departamento
‘Research’ que no tengan personas a cargo.

SELECT ssn
FROM employee
WHERE ssn IN ( SELECT ssn
FROM employee, department

WHERE dno = dnumber

AND dname = ‘Research’)

AND ssn NOT IN ( SELECT essn

FROM dependent);
QFT: Superset

¿Cómo formular que el set B es un superset del set A?

set A set B set A set B


QFT: Superset

¿Cómo formular que el set B es un superset del set A?

If set A - set B es vacio then


set B es superset
set A set B else set B no contiene a
todo elemento de set A
QFT: Superset
¿Cómo formular que el set1 es un superset (contiene)
de otro conjunto, digamos set2?

set1 CONTAINS set2 <=> set2 - set1 = EMPTY

SELECT …
FROM …
WHERE NOT EXISTS (SELECT *
FROM <table>

WHERE x IN set2

AND x NOT IN set1);
QFT: Subset
¿Cómo formular que el set1 es un subset (parte de) de
otro conjunto, digamos set2?

set1 SUBSET set2 <=> set1 - set2 = EMPTY

SELECT …
FROM …
WHERE NOT EXISTS (SELECT *
FROM <table>

WHERE x IN set1

AND x NOT IN set2);
Subset vs Superset

• La sintaxis es casi la misma, sólo la consulta anidada es


distinta

• Las relaciones especificadas para IN y NOT IN hacen la


diferencia para la consultas subset vs superset

(SELECT *
 (SELECT *

FROM <table> FROM <table>

WHERE x IN set2
 WHERE x IN set1
AND x NOT IN set1) AND x NOT IN set2)
set1 superset of set2 set1 subset of set2
QFT: Division
• ¿Cómo calcular la división entre dos relaciones?

• Ejemplo: Buscar el nombre de todos los empleados


que trabajan en todos los proyectos controlado por el
departamento numero 4

• AR:
H1 = ⇡pnumber (PROJECT ./dnum=dnumber dnumber=4 (DEPARTMENT))
H2 = ⇡essn,pno (WORKS ON)
H3 = H2 ÷ H1
Answer = ⇡fname,lname (EMPLOYEE ./ssn = ssn H3)
QFT: Division

• ¿Cómo calcular la división entre dos relaciones?

• Ejemplo: Buscar el nombre de todos los empleados que


trabajan en todos los proyectos controlado por el
departamento numero 4

 SQL: Usar NOT EXISTS y diferencia de conjuntos

 Usar la idea de superset — el conjunto de proyectos


trabajados por un empleado contiene el conjunto de
proyectos controlados por el departamento 4
Ejemplo: DIVISION
Buscar el nombre y el apellido de todos los empleados que trabajan en
todos los proyectos controlado por el departamento numero 4

SELECT fname, lname


FROM employee
WHERE NOT EXISTS
( SELECT pnumber

FROM project

WHERE pnumber IN (SELECT pnumber
 proyectos
FROM project

WHERE dnum = 4)
controlados
AND pnumber NOT IN (SELECT pno por Research
proyectos FROM works_on

trabajados por WHERE essn = ssn));
el empleado
QFT: Only

• ¿Cómo calcular las consultas que piden por "sólo"?

• Ejemplo: Buscar los nombres de los proyectos en los


que trabajan sólo los empleados del departamento
‘Research’

• Formular la solución usando una condición de subset:

 Empleados que trabajan en el proyecto p son un


subset de empleados que trabajan el
departamento 'Research'
Ejemplo: Only
Buscar los nombres de los proyectos en los que trabajan sólo los
empleados del departamento ‘Research’

SELECT pname
FROM project
WHERE NOT EXISTS
( SELECT ssn

FROM employee

WHERE ssn IN (SELECT essn
 empleados que
FROM works_on
 trabajan en el
WHERE pno = pnumber) proyecto p
AND ssn NOT IN (SELECT ssn
empleados del FROM employee, department

WHERE dno = dnumber

departamento AND dname = ‘Research’));
Research
QFT: Mayor número de
• ¿Cómo calcular las consultas que piden por el mayor número
de algún atributo?

• Ejemplo: ¿Buscar el nombre de los departamentos con mayor


número de empleados?
Resp: Usar consulta anidada con la función max

SELECT dname

FROM department, employee

WHERE dno = dnumber

GROUP BY dname

HAVING COUNT(ssn) = (SELECT MAX(no_emp) FROM
(SELECT COUNT(ssn) AS no_emp
FROM employee GROUP BY dno) ce);
Ejercicios SQL (1)

• Encontrar el nombre de los departamentos con 2 o mas


empleados masculinos

• Encontrar el nombre de los empleados con el mayor


numero de personas a cargo

• Encontrar el nombre y el apellido de los empleados que


trabajan en todos los proyectos en los que trabaja John
Smith
Ejercicios SQL (2)

• Buscar el nombre del departamento y el número de


empleados en ese departamento que ganan más de
40K para departamentos con al menos 2 empleados

• Buscar el nombre y el apellido de los empleados que


trabajan en 2 o más proyectos junto con John Smith

• Buscar departamentos que tengan 2 o más empleados


trabajando en todos los proyectos controlados por el
departamento de 'Research'
Ejercicios SQL (3)
• Buscar el nombre del proyecto y el número de
empleados que trabajan en ese proyecto; para
proyectos que tienen 3 más empleados trabajando en el
proyecto

• Buscar el nombre y el apellido de los empleados con


más de 2 personas a cargas y trabajen en más de 2
proyectos

• Buscar el nombre y el apellido de los empleados con


más de 2 personas a cargo y trabajen en todos los
proyectos controlados por el departamento #1
Consultas SQL Avanzadas: Resumen

• Relación Temporal

• Clausula WITH

• Tabla Temporary

• Operaciones JOIN

• Operaciones SQL de conjuntos

• Formulación de operaciones de conjunto


Referencias

• SQL Advanced Queries. http://joyceho.github.io/


cs377_s17/slide/10-11-adv-sql.pdf

• Mysql Reference 5.7 Manual. https://


dev.mysql.com/doc/refman/5.7/en/

• Mysql Reference 8.0 Manual. https://


dev.mysql.com/doc/refman/8.0/en/