SQL Requêtes avancées : imbrication de requêtes, agrégats BD4 SB FC N GdR Licence MASS, Master ISIFAR, Paris-Diderot Février 2015 BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 1/45 Février 2015 1 / 45
Requêtes avancées Manipulations ensemblistes Le résultat d une requête SQL est un ensemble de tuples donc une relation (virtuelle) On peut utiliser ces résultats comme données d une autre requête Moyens : utiliser des fonctions ensemblistes dans la clause WHERE BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 2/45 Février 2015 2 / 45
Requêtes avancées Opérateur IN Utilisation de sous-requêtes : IN Opérateur IN déjà vu pour exprimer que l attribut est à valeur dans une certain liste Nouvelle utilisation de IN avec des sous-requêtes < attribut > [ NOT ] IN (< sous - requête >) Evaluée à vraie si <attribut> appartient au résultat de la sous-requête BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 3/45 Février 2015 3 / 45
Requêtes avancées Opérateur IN Utilisation de sous-requêtes : IN Exemples Liste des joueurs cancadiens SELECT DISTINCT last_name, first_name FROM player WHERE code IN ( SELECT code FROM country_codes WHERE country = Canada ) ; est équivalente à : SELECT DISTINCT last_name, first_name FROM player p, country_codes cc WHERE (p code = cc code ) AND ( cc country = Canada ) BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 4/45 Février 2015 4 / 45
Requêtes avancées Opérateur IN Utilisation de sous-requêtes : IN Exemples : Lister les tournois auxquels a participé Federer SELECT DISTINCT ON ( name ) name, location, date_part ( YEAR, startdate ), surface FROM tournament_big WHERE tid IN ( SELECT tid FROM played_in_big WHERE registrnum IN ( SELECT registrnum FROM registration_big WHERE pid IN ( SELECT pid FROM player_big WHERE last_name = Federer ))) BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 5/45 Février 2015 5 / 45
Requêtes avancées Opérateur IN Utilisation de sous-requêtes : IN Pratique à utiliser sous la forme NOT IN Les tournois auxquels Federer n a pas participé SELECT DISTINCT ON ( name ) name, location, date_part ( YEAR, startdate ), surface FROM tournament WHERE tid NOT IN ( SELECT tid FROM played_in WHERE registrnum IN ( SELECT registrnum FROM registration WHERE pid IN ( SELECT pid FROM player WHERE last_name = Federer ))) BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 6/45 Février 2015 6 / 45
Requêtes avancées Opérateur ALL et ANY Utilisation de sous-requêtes : ANY, ALL Deux nouveaux opérateurs manipulant des sous-requêtes : ANY, ALL < attributs > = < > <= < > = > ANY (< sous - requête >) évaluée à vraie si au moins un des résultats de la sous requête vérifie la comparaison avec <attributs> < attributs > = < > <= < > = > ALL (< sous - requête >) évaluée à vraie si tous les résultats de la sous requête vérifient la comparaison avec <attributs> Nota < attributs > : peut être une liste d attributs BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 7/45 Février 2015 7 / 45
Requêtes avancées Opérateur ALL et ANY Utilisation de sous-requêtes : ANY, ALL Exemple (alternative au IN) : SELECT DISTINCT ON ( name ) name, location, date_part ( YEAR, startdate ), surface FROM tournament_big WHERE tid = ANY ( SELECT tid FROM played_in_big WHERE registrnum IN ( SELECT registrnum FROM registration_big WHERE pid IN ( SELECT pid FROM player_big WHERE last_name = Federer )) BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 8/45 Février 2015 8 / 45
Opérateur EXISTS Utilisation de sous-requêtes : EXISTS [NOT] EXISTS (<sous-requête>) évaluée à vraie si la sous-requête renvoie au moins un résultat Exemple : Nom, Prenom des joueurs défaits par Nadal Il faut d abord déterminer les rencontres où Nadal a gagné et en déduire les numéro d inscription des perdants de ces rencontres Différence avec ANY utilisation de EXISTS s apparente à une condition Booléenne Pas de test sur la valeur d un attribut particulier BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 11/45 Février 2015 11 / 45
Opérateur EXISTS Les joueurs vaincus par Nadal SELECT DISTINCT ON ( last_name, first_name ) * FROM atp player p2 WHERE EXISTS ( SELECT * FROM atp registration r2 JOIN atp game g ON ( r2 registrnum =g registrnum2 ) JOIN atp registration r1 ON ( r1 registrnum =g registrnum1 ) WHERE p2 pid = r2 pid AND r1 pid =1) Remarques pid=1 est le numéro de Rafael Nadal et dans la relation game Dans l état actuel de la base, le numéro d inscription du vainqueur est registrnum1 BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 12/45 Février 2015 12 / 45
Opérateur EXISTS Intersection, Union, Différence Opérateurs ensemblistes On peut disposer (suivant les implémentations) des opérateurs ensemblistes Intersection Union < requête1 > INTERSECT < requête2 > < requête1 > UNION < requête2 > Différence < requête1 > EXCEPT < requête2 > En PostgreSQL : UNION, INTERSECT et EXCEPT sont proposés BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 14/45 Février 2015 14 / 45
Opérateur EXISTS Intersection, Union, Différence NOT EXISTS versus NOT IN Sur le papier L utisation de NOT EXISTS et des sous-requêtes corrélées permet d émuler complètement la différence NOT IN convient lorsque le critère d élimination porte sur une seule colonne Le procédé NOT EXISTS peut s avérer couteux si les tables ne sont pas convenablement indexées Si les deux tables disposent d une clé primaire commune, NOT IN opérant sur les clés primaires suffit BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 17/45 Février 2015 17 / 45
Sous requêtes : WITH Sous-requêtes nommées, clause WITH WITH with_query_name [ ( column_name [, ] ) AS ( SELECT ) SELECT FROM WHERE GROUP BY HAVING ORDER BY Rôle de la sous-requête nommée BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 18/45 Février 2015 18 / 45
La division Division Rappel d algèbre relationnelle : division de R par S - relation R de schéma R(A 1, A 2,, A k ) - relation S de schéma S(A p+1,, A k ) (Schema de S Schema de R) La division (ou le quotient) de R par S est une relation T de schéma T (A 1,, A p ) formée des tuples qui, concaténés à chaque tuple de S, donnent un tuple de R On note T = R S BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 20/45 Février 2015 20 / 45
La division Définition de la division Arbre de requêtes - R de schéma R(A 1, A 2,, A k ), S de schéma S(A p+1,, A k ) est la relation T = R S de schéma T (A 1,, A p ) π A1,,A p R S π A1,,A p R π A1,,A p R BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 21/45 Février 2015 21 / 45
La division Division en SQL (PostgreSQL) WITH Rp AS ( SELECT A1,, Ap FROM R ) SELECT * FROM Rp EXCEPT SELECT A1,, Ap FROM ( SELECT * FROM Rp, S EXCEPT SELECT * FROM R) R2 ; BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 22/45 Février 2015 22 / 45
La division Exemple WITH R AS ( SELECT tid, pid FROM atp participations WHERE date_part =2008 AND surface = Clay ), S AS ( SELECT DISTINCT tid FROM R), Rp AS ( SELECT DISTINCT pid FROM R) SELECT pid FROM Rp EXCEPT SELECT pid FROM ( SELECT tid, pid FROM Rp,S EXCEPT SELECT * FROM R) U ; La construction WITH permet de simplifier l écriture BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 23/45 Février 2015 23 / 45
La division Illustration de la division Lister les joueurs qui participé à tous les tournois sur terre battue en 2008 On construit une table intermédiaire, la table des couples pid,tid où tid est le numéro d un tournoi disputé en 2008 sur terre battue et pid BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 25/45 Février 2015 25 / 45
La division Exemples Nom, prénom des joueurs qui ont participé à tous les tournois à plus de 5 tours disputés en 2008 sur terre battue SELECT last_name, first_name, pid FROM atp player WHERE pid IN ( WITH R AS ( SELECT tid, pid FROM atp participations WHERE date_part =2008 AND surface = Clay AND numrounds >5), S AS ( SELECT DISTINCT tid FROM R), Rp AS ( SELECT DISTINCT pid FROM R) SELECT pid FROM Rp EXCEPT SELECT pid FROM ( SELECT tid, pid FROM Rp,S EXCEPT SELECT * FROM R) U) ORDER by last_name ; BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 26/45 Février 2015 26 / 45
Agrégats Fonctions SUM et AVG Fonctions d agrégation en SQL Possibilité de compter, de faire des moyennes, de prendre un maximum en SQL (contrairement à l algèbre relationnelle classique ) Possibilité de partitionner et regrouper les données Dans la partie SELECT SUM ( DISTINCT ALL < nomattribut >) Somme des valeurs prises par nomattribut AVG ( DISTINCT ALL < nom_attribut >) Moyenne des valeurs prises par nomattribut Le type des attributs doit être un nombre ou un entier (sinon, pas possible de compter) BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 27/45 Février 2015 27 / 45
Agrégats Fonctions SUM et AVG Fonctions d agrégation : SUM et AVG Exemple : nombre moyen de sets par rencontre pour les tournois disputés sur terre battue SELECT AVG ( numsets ) FROM tournament t JOIN game g ON (t tid =g tid ) JOIN match_results m ON (g mid =m mid ) WHERE t surface = Clay ; BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 28/45 Février 2015 28 / 45
Agrégats Fonctions MAX et MIN Fonctions de calcul : MAX,MIN Usage MAX (< nomattribut >) maximum des valeurs prises par <nomattribut> MIN (< nomattribut >) minimum des valeurs prises par <nomattribut> Nombre maximal de jeux disputés dans un set SELECT MAX ( winnergames + losergames ) FROM setscore BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 30/45 Février 2015 30 / 45
Agrégats Fonction COUNT Fonctions de calcul : COUNT On peut aussi compter le nombre de tuples dans un résultat de requête COUNT (* [ ALL DISTINCT < nomattribut >]) nombre de valeurs prises par le résultat DISTINCT : sans les doublons ALL : avec les doublons * : y compris les valeurs nulles BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 31/45 Février 2015 31 / 45
Agrégats Fonction COUNT Exemple : Nombre de tournois disputés par Federer SELECT COUNT (*) FROM tournament_big WHERE tid = ANY ( SELECT tid FROM played_in_big WHERE registrnum IN ( SELECT registrnum FROM registration_big WHERE pid IN ( SELECT pid FROM player_big WHERE last_name = Federer ))) BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 32/45 Février 2015 32 / 45
Partition et groupe GROUP BY Partition de résultats de requêtes GROUP BY < nomattribut1 >,, < nomattributn > GROUP BY permet de regrouper par valeur de certains attributs l ensemble des résultats d une requête Forme des sous-relations auxquelles on peut appliquer des opérateurs (SUM, MAX, ) renvoyant un résultat unique par groupe Exemple d utilisation : regrouper les livraisons par numéro de fournisseur et prendre la quantité maximum livrée par fournisseur BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 35/45 Février 2015 35 / 45
Partition et groupe GROUP BY Partition de résultats de requêtes Quel est le sens de cette requête? SELECT first_name, COUNT (*) FROM atp player GROUP BY first_name Les attributs présents dans le SELECT sont forcément présents dans le GROUP BY Pourquoi? ie cette requête a-t-elle un sens? SELECT last_name, first_name, MAX ( code ) FROMatp player GROUP BY first_name BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 38/45 Février 2015 38 / 45
Partition et groupe GROUP BY Partition de résultats de requêtes La clause HAVING permet de poser une condition portant sur chacune des sous-relations générées par le GROUP BY Les sous-relations ne vérifiant pas la condition sont écartées du résultat Exemple : liste des pays qui comptent plus de 3 joueurs SELECT code FROM atp player GROUP BY code HAVING COUNT (*) >= 3 BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 39/45 Février 2015 39 / 45
Partition et groupe Présentation/tri de résultats Tri des résultats La clause ORDER BY permet de trier le résultat de la requête, en fournissant la liste des attributs sur lesquels effectuer le tri et en spécifiant le sens du tri (ascendant ou descendant) Exemple : liste des tournois sur terre battue par date de commencement décroissante salaire SELECT name, location, startdate FROM tournament WHERE surface = Clay ORDER BY startdate DESC BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 40/45 Février 2015 40 / 45
Partition et groupe Tri des résultats Regroupement, tri, etc : exemple Exemple : Que fait cette requête? SELECT surface, date_part ( MONTH, startdate ) mois, COUNT (*) nombre FROM atp tournament WHERE numrounds >5 AND ttype LIKE Singles GROUP BY surface, date_part ( MONTH, startdate ) HAVING COUNT (*) >2 ORDER BY mois ; BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 42/45 Février 2015 42 / 45
Partition et groupe Tri des résultats Une sortie surface mois nombre Hard 1 16 Hard 3 30 Clay 4 32 Clay 5 44 Grass 6 31 Clay 7 18 Hard 7 16 Hard 8 61 Hard 9 3 Carpet 10 6 Hard 10 24 Hard 11 3 (12 rows) Pour chaque mois calendaire, chaque surface, le nombre de tournois disputés en simple, comprenant plus de 5 tours (si ce nombre est supérieur à 2), trié par mois Que serait le nombre moyen de tournois disputés en simple, par mois et par surface? BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 43/45 Février 2015 43 / 45
Une réponse Partition et groupe Tri des résultats SELECT surface, date_part ( MONTH, startdate ) mois, COUNT (*)/ COUNT ( DISTINCT date_part ( YEAR, startdate )) moyenne FROM atp tournament WHERE ttype LIKE Singles GROUP BY surface, date_part ( MONTH, startdate ) ORDER BY mois ; surface mois moyenne Carpet 1 1 Clay 1 1 Hard 1 6 Carpet 2 1 Clay 2 3 Hard 2 6 Clay 3 1 Hard 3 2 Clay 4 6 Clay 5 4 Clay 6 1 Grass 6 5 Clay 7 6 Grass 7 1 Hard 7 2 Clay 8 1 Hard 8 4 (25 rows) BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 44/45 Février 2015 44 / 45
Conclusion Résumé Syntaxe générale SELECT < attributs > FROM < relations > [ WHERE < condition > ] [ GROUP BY < attributs de partitionnement > [ HAVING < condition >] ] [ ORDER BY < critere >] SELECT : attributs du résultat (avec agrégats éventuels) WHERE : condition de sélection indépendante du Group By HAVING : condition de sélection portant sur les agrégats BD4 (Licence MASS, Master ISIFAR, Paris-Diderot) SQL 45/45 Février 2015 45 / 45