Bases de Données TD : langage assertionnel SQL Corrigé Liste des requêtes à exprimer en SQL. Tracer le graphe des clés étrangères avant de commencer à répondre aux requêtes. ERSONNE Requête 3 : Donner la liste de tous les genres de film. SELECT DISTINCT GENRE Requête 4 : Trouver le titre et l année des films de science fiction dont le budget dépasse 5.000.000 $. SELECT TITRE, ANNÉE WHERE GENRE = Scii AND BUDGET > 5000000 GENRE = Scii ACTEUR CINÉMA BUDGET > 5000000 DISTRIBUTION TITRE, ANNÉE ILM Requêtes élémentaires ASSE SALLE Requête 1 : Retrouver la liste de tous les films. Requête 2 : Retrouver la liste des films dont la longueur dépasse 180 min. WHERE LONGUEUR > 180 Requête 5 : Donner le nombre de films par genre. SELECT GENRE, COUNT (*) GROU BY GENRE Requête 6 : Donner le nombre de films de 1960 par genre. SELECT GENRE, COUNT (*) WHERE ANNÉE = 1960 GROU BY GENRE
Requêtes faciles la requête imbriquée ne contribue pas au résultat Requête 7 : Trouver le titre des films réalisés par Roman olanski. orme plate : SELECT.TITRE, ERSONNE WHERE.RÉALISATEUR =.NUM AND.RÉNOM = Roman AND.NOM = olanski RÉALISATEUR = NUM TITRE RÉNOM = Roman NOM = olanski RÉALISATEUR = NUM RÉNOM = Roman NOM = olanski Requête 8 : Quels sont les acteurs comiques (nom, prénom) qui ont joué dans un film de Spielberg. TITRE SÉCIALITÉ = Comique orme imbriquée : SELECT TITRE WHERE RÉALISATEUR IN ( WHERE RÉNOM = Roman AND NOM = olanski ) A NUM = NUMA RÉNOM, NOM D NUM = NUM RÉALISATEUR = NUMA R NOM = Spielberg orme plate : SELECT A.RÉNOM, A.NOM A, DISTRIBUTION D, ILM, ERSONNE R WHERE A.NUM = D.NUMA Corrigé du TD SQL (BD-ilmographie) 2
AND AND AND AND D.SÉCIALITÉ = Comique D.NUM =.NUM.RÉALISATEUR = R.NUM R.NOM = Spielberg orme imbriquée : SELECT RÉNOM, NOM SELECT NUMA ROM DISTRIBUTION WHERE SÉCIALITÉ = Comique AND NUM IN ( WHERE RÉALISATEUR IN ( ROMERSONNE WHERE NOM = Spielberg ) ) ) seule la variable A contribue au résultat, on obtient trois niveaux d imbrication Requête 9 : Trouver le titre et l année du film le plus long. orme imbriquée : SELECT TITRE, ANNÉE WHERE LONGUEUR = ( SELECT MAX (LONGUEUR) ) Requêtes de difficulté moyenne Requête 10 : Nom et prénom des acteurs qui ont joué Gavroche dans les différentes versions des «Misérables» avec les dates correspondantes. orme plate : SELECT.RÉNOM,.NOM,.DATE, DISTRIBUTION D, ILM WHERE.NUM = D.NUMA AND D.RÔLE = Gavroche AND G.NUM =.NUM AND.TITRE = Les misérables A NUM = NUMA RÉNOM, NOM SÉCIALITÉ = Comique D NUM = NUM RÉALISATEUR = NUMA R NOM = Spielberg NUM = NUMA RÉNOM, NOM RÔLE = Gavroche D NUM = NUM DATE TITRE = Les misérables Corrigé du TD SQL (BD-ilmographie) 3
orme imbriquée SQL-92 : SELECT.RÉNOM,.NOM,.DATE, ILM WHERE.TITRE = Les misérables AND (.NUM,.NUM) IN ( SELECT NUMA, NUM ROM DISTRIBUTION WHERE RÔLE = Gavroche ) la requête imbriquée ne contribue pas au résultat et est liée deux fois à la requête englobante orme imbriquée SQL-92 : SELECT DISTINCT RÉNOM, NOM SELECT RÉALISATEUR WHERE (RÉALISATEUR, NUM) IN ( SELECT NUMA, NUM ROM DISTRIBUTION ) ) RÉALISATEUR = NUMA NUM = NUMA RÉNOM, NOM RÔLE = Gavroche D NUM = NUM DATE TITRE = Les misérables RÉALISATEUR = NUM NUM = NUM RÉNOM, NOM D NUM = NUMA Requête 11 : Donner le nom et le prénom des réalisateurs qui ont joué dans au moins un de leurs propres films. orme plate : SELECT DISTINCT.RÉNOM,.NOM, ILM, DISTRIBUTION D WHERE.NUM =.RÉALISATEUR AND.NUM = D.NUM AND D.NUMA =.RÉALISATEUR Requête 12 : Quel est le total des salaires des acteurs du film «Nuits blanches à Seattle». orme plate : SELECT SUM (D.SALAIRE) ROM DISTRIBUTION D, ILM WHERE DISTRIBUTION.NUM =.NUM AND.TITRE = Nuits blanches à Seattle orme imbriquée : SELECT SUM (SALAIRE) Corrigé du TD SQL (BD-ilmographie) 4
ROM DISTRIBUTION WHERE NUM IN ( WHERE TITRE = Nuits blanches à Seattle ) Requête 14 : Trouver le genre des films des années 80 dont le budget moyen dépasse 200.000 $. SELECT GENRE WHERE ANNÉE BETWEEN 1980 AND 1989 GROU BY GENRE HAVING AVG (BUDGET) > 200000 D NUM = NUM TITRE = Nuits blanches à Seattle Requêtes plus complexes Requête 15 : our chaque film de Spielberg (titre, année), donner le total des salaires des acteurs. SALAIRE SUM Requête 13 : Donner la moyenne des salaires des acteurs par film, avec le titre et l année correspondants. orme SQL-89 : SELECT.TITRE,.ANNÉE, AVG (D.SALAIRE), DISTRIBUTION D WHERE.NUM = D.NUM GROU BY.TITRE,.ANNÉE orme SQL-92 : SELECT.TITRE,.ANNÉE, AVG (D.SALAIRE), DISTRIBUTION D WHERE.NUM = D.NUM GROU BY.NUM -- Si NUM a bien été déclaré clé primaire de la relation ILM orme plate : SELECT.TITRE,.ANNÉE, SUM (D.SALAIRE), DISTRIBUTION D, ERSONNE WHERE.NUM = D.NUM AND.RÉALISATEUR =.NUM AND.NOM = Spielberg GROU BY.TITRE,.ANNÉE orme imbriquée SQL-89 : SELECT.TITRE,.ANNÉE, SUM (D.SALAIRE), DISTRIBUTION D WHERE.NUM = D.NUM AND.RÉALISATEUR IN ( WHERE NOM = Spielberg ) GROU BY.TITRE,.ANNÉE orme imbriquée SQL-92 : SELECT.TITRE,.ANNÉE, X.SUMSAL, (, SUM (SALAIRE) AS SUMSAL ROM DISTRIBUTION Corrigé du TD SQL (BD-ilmographie) 5
GROU BY NUM ) AS X WHERE.NUM = X.NUM AND.RÉALISATEUR IN ( WHERE NOM = Spielberg ) Requête 16 : Lister les cinémas dont la taille moyenne d'écran est supérieure à 40 mètres carrés. orme plate : SELECT C.NOM, C.VILLE ROM CINÉMA C, SALLE S WHERE C.NUMC = S.NUMC GROU BY C.NUMC, C.NOM, C.VILLE HAVING AVG (S.TAILLE_ÉCRAN) > 40 ) orme imbriquée SQL-92 : SELECT NOM, VILLE ROM CINÉMA WHERE NUMC IN ( SELECT NUMC ROM SALLE GROU BY NUMC HAVING AVG (TAILLE_ÉCRAN) > 40 ) Requête 17 : Quels sont les cinémas arisiens de la ox, avec le film correspondant, qui passent un film d'elia Kazan avant 22 heures dans une salle d'au moins 200 places et d'écran de taille supérieure à 30 m carrés. orme plate : SELECT DISTINCT C.NOM,.TITRE ROM CINÉMA C, SALLE S, ASSE, ILM, ERSONNE WHERE C.COMAGNIE = ox AND C.VILLE = aris AND C.NUMC = S.NUMC AND S.NBLACES >= 200 AND S.TAILLE_ÉCRAN > 30 AND S.NUMC =.NUMC AND S.NUMS =.NUMS AND.HORAIRE < 22 :00 AND.NUM =.NUM AND.RÉALISATEUR =.NUM AND.RÉNOM = Elia AND.NOM = Kazan NUMC = NUMC C TAILLE_ÉCRAN > 30 NBLACES >= 200 S NOM NUMC = NUMC NUMS = NUMS HORAIRE < 22:00 NUM = NUM TITRE orme imbriquée SQL-89 : SELECT DISTINCT C.NOM,.TITRE ROM CINÉMA C, SALLE S, ASSE, ILM WHERE C.COMAGNIE = ox AND C.VILLE = aris AND C.NUMC = S.NUMC AND S.NBLACES >= 200 AND S.TAILLE_ÉCRAN > 30 AND S.NUMC =.NUMC AND S.NUMS =.NUMS AND.HORAIRE < 22 :00 AND.NUM =.NUM RÉALISATEUR = NUMA R NOM = Spielberg Corrigé du TD SQL (BD-ilmographie) 6
AND.RÉALISATEUR IN ( WHERE RÉNOM = Elia AND NOM = Kazan ) NUM = NUM NUMC = NUMC COMAGNIE = ox orme imbriquée SQL-92 : SELECT DISTINCT C.NOM,.TITRE ROM CINÉMA C, ILM WHERE C.COMAGNIE = ox AND C.VILLE = aris AND (C.NUMC,.NUM) IN ( SELECT S.NUMC,.NUM ROM SALLE S, ASSE WHERE S.NBLACES >= 200 AND S.TAILLE_ÉCRAN > 30 AND S.NUMC =.NUMC AND S.NUMS =.NUMS AND.HORAIRE < 22 :00 ) AND.RÉALISATEUR IN ( WHERE RÉNOM = Elia AND NOM = Kazan ) Requête 18 : Trouver le titre des films qui ne passent à aucun cinéma de la compagnie OX. On commence par poser la requête inverse : les films qui passent dans un (au moins) cinéma de la ox. orme plate : pour trouver ceux qui passent dans un cinéma de la ox SELECT DISTINCT.NUM,.TITRE, ASSE, CINÉMA C WHERE.NUM =.NUM AND.NUMC = C.NUMC AND C.COMAGNIE = ox NUM, TITRE orme imbriquée 1 prédicat IN : pour trouver ceux qui passent dans un cinéma de la ox SELECT DISTINCT NUM, TITRE WHERE NUM IN ( ROM ASSE WHERE NUMC IN ( SELECT NUMC ROM CINÉMA WHERE COMAGNIE = ox ) ) orme imbriquée 2 prédicat EXISTS : toujours pour trouver ceux qui passent dans un cinéma de la ox SELECT DISTINCT NUM, TITRE WHERE EXISTS ( ROM ASSE WHERE.NUM =.NUM AND EXISTS ( C Corrigé du TD SQL (BD-ilmographie) 7
ROM CINÉMA C WHERE C.NUMC =.NUMC AND COMAGNIE = ox ) ) La négation de ces deux dernières formes permet d exprimer la requête initiale : les films qui ne passent à aucun des cinémas de la ox. orme imbriquée 1 prédicat NOT IN : pour trouver ceux qui ne passent dans aucun cinéma de la ox SELECT DISTINCT NUM, TITRE WHERE NUM NOT IN ( ROM ASSE WHERE NUMC IN ( SELECT NUMC ROM CINÉMA WHERE COMAGNIE = ox ) ) orme imbriquée 2 prédicat NOT EXISTS : pour trouver ceux qui ne passent dans aucun cinéma de la ox SELECT DISTINCT NUM, TITRE WHERE NOT EXISTS ( ROM ASSE WHERE.NUM =.NUM AND EXISTS ( ROM CINÉMA C WHERE C.NUMC =.NUMC AND COMAGNIE = ox ) ) our finalement arriver à la forme la plus simple, où seul le prédicat NOT EXISTS provoque un niveau d imbrication. orme 3 prédicat NOT EXISTS uniquement : SELECT DISTINCT NUM, TITRE WHERE NOT EXISTS ( ROM ASSE, CINÉMA C WHERE.NUM =.NUM AND.NUMC = C.NUMC AND COMAGNIE = ox ) Si on est très pointilleux, on peut remarquer que la question «qui ne passent à aucun» peut être comprise comme ne devant retourner que les films actuellement programmés, mais pas dans un cinéma de la ox. Si la relation ILM comporte tous les films qui ont été programmés, on peut modifier la requête comme suit : orme complète : SELECT DISTINCT NUM, TITRE WHERE NUM IN ( ROM ASSE ) AND NOT EXISTS ( ROM ASSE, CINÉMA C WHERE.NUM =.NUM AND.NUMC = C.NUMC AND COMAGNIE = ox ) Requête 19 : Trouver le nom et le prénom des acteurs qui ont eu un salaire plus important dans un film particulier que le salaire du réalisateur du même film. En supposant pour simplifier que les acteurs n ont joué qu un seul rôle dans le film. orme plate : SELECT A.RÉNOM, A.NOM A, DISTRIBUTION D, ILM WHERE A.NUM = D.NUMA Corrigé du TD SQL (BD-ilmographie) 8
AND AND D.NUM =.NUM D.SALAIRE >.SALAIRE_RÉAL SALAIRE_RÉAL < SALAIRE NUM = NUM RÉNOM, NOM D NUM = NUMA orme imbriquée 1 : SELECT RÉNOM, NOM SELECT D.NUMA ROM DISTRIBUTION D, ILM WHERE D.NUM =.NUM AND D.SALAIRE >.SALAIRE_RÉAL ) orme imbriquée 2 : SELECT RÉNOM, NOM SELECT NUMA ROM DISTRIBUTION D WHERE D.SALAIRE > ( SELECT.SALAIRE_RÉAL WHERE D.NUM =.NUM ) ) En tenant compte de la possibilité que les acteurs aient joué plusieurs rôles dans le film, et en supposant qu ils touchent un salaire pour chaque rôle dans ce cas. (NB : cela ne reflète pas forcément les pratiques de l industrie du cinéma, mais pour faire plus proche de la réalité, il faudrait compliquer sensiblement le schéma de la base). orme imbriquée SQL-89 : SELECT DISTINCT A.RÉNOM, A.NOM A, DISTRIBUTION D WHERE A.NUM = D.NUMA GROU BY D.NUMA, D.NUM, A.RÉNOM, A.NOM HAVING SUM (SALAIRE) > ( SELECT SALAIRE_RÉAL WHERE D.NUM =.NUM ) ) orme imbriquée SQL-92 : SELECT RÉNOM, NOM SELECT NUMA ROM DISTRIBUTION D GROU BY NUMA, NUM HAVING SUM (SALAIRE) > ( SELECT SALAIRE_RÉAL WHERE D.NUM =.NUM ) ) Requêtes difficiles Requête 20 : Trouver les couples acteur-réalisateur (noms et prénoms) tels que l un a dirigé l autre sur un film et vice-versa sur un autre. orme plate : SELECT DISTINCT 1.RÉNOM, 1.NOM, 2.RÉNOM, 2.NOM 1, ERSONNE 2, ILM 1, ILM 2, Corrigé du TD SQL (BD-ilmographie) 9
DISTRIBUTION D1, DISTRIBUTION D2 WHERE 1.NUM > 2.NUM -- ERMET D ÉLIMINER DEUX ROBLÈMES : -- LISTER UN COULE (1, 2) UNE SEULE OIS -- DANS UN SEUL ORDRE -- ÉLIMINER LE CAS DES RÉALISATEURS QUI ONT JOUÉ -- DANS LEUR RORE ILM AND 1.NUM = 1.RÉALISATEUR AND 2.NUM = 2.RÉALISATEUR AND 1.NUM = D1.NUM AND D1.NUMA = 2.RÉALISATEUR AND 2.NUM = D2.NUM AND D2.NUMA = 1.RÉALISATEUR D1 NUM = NUM RÉALISATEUR = NUMA 1 NUMA = RÉALISATEUR NUMA = NUM 1 RÉNOM, NOM NUM > NUM 1 RÉNOM, NOM 1 NUMA = RÉALISATEUR RÉALISATEUR = NUMA NUM = NUMA NUM = NUM orme imbriquée SQL-92 : SELECT DISTINCT 1.RÉNOM, 1.NOM, 2.RÉNOM, 2.NOM 1, ERSONNE 2 WHERE (1.NUM, 2.NUM) IN ( SELECT 1.RÉALISATEUR, 2.RÉALISATEUR 1, ILM 2, DISTRIBUTION D1, DISTRIBUTION D2 WHERE 1.RÉALISATEUR > 2.RÉALISATEUR -- ERMET D ÉLIMINER DEUX ROBLÈMES : -- LISTER UN COULE (RÉAL1, RÉAL2) UNE SEULE OIS D1 -- DANS UN SEUL ORDRE -- ÉLIMINER LE CAS DES RÉALISATEURS QUI ONT JOUÉ -- DANS LEUR RORE ILM AND 1.NUM = D1.NUM AND D1.NUMA = 2.RÉALISATEUR AND 2.NUM = D2.NUM AND D2.NUMA = 1.RÉALISATEUR ) Requête 21 : Trouver le nom, le prénom, le numéro des acteurs qui ont joué dans tous les films de Lelouch, s'il y en a. On peut rephraser logiquement cette requête en remarquant que l on cherche les acteurs des films de Lelouch pour lesquels pour chaque film de Lelouch on peut trouver un tuple dans distribution qui indique que l acteur a bien joué dans ce film. {acteur : " film-de-lelouch, $ distribution tq acteur-a-joué-dans-film } SQL ne comporte pas d équivalent du quantificateur universel ". On doit donc utiliser une transformation logique introduction d une double négation qui produit la négation d un quantificateur existentiel ÿ$ après descente d une des deux négations. {acteur : ÿ$ film-de-lelouch, ÿ$ distribution tq acteur-a-joué-dans-film } Le plus simple est de d abord écrire la requête sans négation en utilisant une forme imbriquée avec des prédicats EXIXTS, puis d introduire une double négation. On commencera donc par chercher le nom, le prénom, le numéro des acteurs qui ont joué dans un des films de Lelouch. orme imbriquée prédicat EXISTS : «dans un des films» SELECT NOM, RÉNOM WHERE EXISTS ( WHERE RÉALISATEUR IN ( WHERE NOM = Lelouch ) AND EXISTS ( Corrigé du TD SQL (BD-ilmographie) 10
ROM DISTRIBUTION D WHERE D.NUM =.NUM AND D.NUMA =.NUM ) ) Il ne reste plus alors qu à introduire les deux négations pour obtenir la requête souhaitée. orme imbriquée prédicat NOT EXISTS : «dans tous les films» SELECT NOM, RÉNOM, NUM WHERE NOT EXISTS ( WHERE RÉALISATEUR IN ( WHERE NOM = Lelouch ) AND NOT EXISTS ( ROM DISTRIBUTION D WHERE D.NUM =.NUM AND D.NUMA =.NUM ) ) Requête 22 : our chaque film de Bergman, trouver le nom et le prénom de l'acteur qui a eu le plus gros salaire. Il faut également rephraser cette requête pour l exprimer de façon logique. La requête consiste à chercher les acteurs pour lesquels, quels que soient les autres acteurs du même film, leur salaire est plus élevé. our simplifier on va d abord se limiter au cas où un acteur ne joue qu un rôle par film. { film, acteur : film Œ film-de-bergman, acteur Œ acteur-ayant-joué-dans-cefilm, " autre-acteur-ayant-joué-dans-ce-film $ distribution tq acteur-a-jouédans-film-avec-plus-gros-salaire-que-autre-acteur } Soit après introduction d une double négation pour éliminer le " : { film, acteur : film Œ film-de-bergman, acteur Œ acteur-ayant-joué-dans-cefilm, ÿ$ autre-acteur-ayant-joué-dans-ce-film ÿ$ distribution tq acteur-a-jouédans-film-avec-plus-gros-salaire-que-autre-acteur } orme imbriquée prédicat NOT EXISTS : un seul rôle par acteur SELECT.TITRE, A.RÉNOM, A.NOM, DISTRIBUTION D1, ERSONNE A WHERE.NUM = D1.NUM AND D1.NUMA = A.NUM AND RÉALISATEUR IN ( WHERE NOM = Bergman ) AND NOT EXISTS ( ROM DISTRIBUTION D2 WHERE D2.NUM = D1.NUM AND D2.SALAIRE > D1.SALAIRE ) En tenant compte maintenant de la possibilité pour un acteur de jouer plusieurs rôles dans un film, on obtient la requête suivante. orme imbriquée SQL-89 + prédicat > ALL : possibilité de plusieurs rôles pour un même acteur SELECT.TITRE, A.RÉNOM, A.NOM, DISTRIBUTION D1, ERSONNE A WHERE.NUM = D1.NUM AND D1.NUMA = A.NUM AND RÉALISATEUR IN ( WHERE NOM = Bergman ) GROU BY D1.NUM, D1.NUMA,.TITRE, A.RÉNOM, A.NOM HAVING SUM (SALAIRE) > ALL ( SELECT SUM (SALAIRE) ROM DISTRIBUTION D2 WHERE D2.NUM = D1.NUM Corrigé du TD SQL (BD-ilmographie) 11
AND D2.NUMA <> D1.NUMA GROU BY D2.NUMA ) orme imbriquée SQL-92 : possibilité de plusieurs rôles pour un même acteur SELECT.TITRE, A.RÉNOM, A.NOM, ERSONNE A WHERE (.NUM, A.NUM) IN ( SELECT D1.NUM, D1.NUMA ROM DISTRIBUTION D1 WHERE D1.NUM IN ( WHERE RÉALISATEUR IN ( WHERE NOM = Bergman ) ) GROU BY D1.NUM, D1.NUMA HAVING SUM (D1.SALAIRE) = ( SELECT MAX ( SELECT SUM (D2.SALAIRE) ROM DISTRIBUTION D2 WHERE D2.NUM = D1.NUM GROU BY D2.NUMA ) ) On peut aussi simplifier en repartant de la requête valable seulement si un acteur ne joue qu un rôle par film et en utilisant une vue groupée à la place de distribution. Utilisation d une vue groupée SQL-92 : CREATE VIEW SALAIRE_TOTAL_ACTEUR_ILM (NUMA, NUM, SALAIRE_TOTAL) AS SELECT NUMA, NUM, SUM (SALAIRE) GROU BY NUMA, NUM SELECT.TITRE, A.RÉNOM, A.NOM, SALAIRE_TOTAL_ACTEUR_ILM D1, ERSONNE A WHERE.NUM = D1.NUM AND D1.NUMA = A.NUM AND RÉALISATEUR IN ( WHERE NOM = Bergman ) AND NOT EXISTS ( ROM SALAIRE_TOTAL_ACTEUR_ILM D2 WHERE D2.NUM = D1.NUM AND D2.SALAIRE_TOTAL > D1.SALAIRE_TOTAL ) Requête 23 : Donner le nom et le prénom des réalisateurs qui ont eu le plus gros salaire sur un de leurs films (par comparaison avec ceux des acteurs). Hypothèse 1 : chaque acteur ne joue qu un rôle, le réalisateur ne joue pas dans le film correspondant. orme imbriquée : SELECT RÉNOM, NOM SELECT RÉALISATEUR WHERE SALAIRE_RÉAL > ( SELECT MAX (SALAIRE) ROM DISTRIBUTION D WHERE D.NUM =.NUM ) ) Hypothèse 2 : un acteur peut jouer plusieurs rôles, le réalisateur ne joue pas dans le film correspondant. orme imbriquée : SELECT RÉNOM, NOM SELECT RÉALISATEUR Corrigé du TD SQL (BD-ilmographie) 12
WHERE SALAIRE_RÉAL > ALL ( SELECT SUM (SALAIRE) ROM DISTRIBUTION D WHERE D.NUM =.NUM GROU BY NUMA ) ) Hypothèse 3 : Tout acteur y compris le réalisateur s il joue dans le film correspondant peut jouer plusieurs rôles. orme imbriquée SQL-92 : SELECT RÉNOM, NOM SELECT RÉALISATEUR WHERE SALAIRE_RÉAL + ( SELECT SUM (SALAIRE) ROM DISTRIBUTION D1 WHERE D1.NUM =.NUM AND D1.NUMA =.RÉALISATEUR ) > ( SELECT MAX ( SELECT SUM (SALAIRE) ROM DISTRIBUTION D2 WHERE D2.NUM =.NUM GROU BY D2.NUMA ) ) ) Schéma complémentaire RÉCOMENSE (NUMR, CATÉGORIE, ESTIVAL) RÉCOMENSE_ILM (NUM, ANNÉE, NUMR) RÉCOMENSE_ACTEUR (NUMA, NUM, ANNÉE, NUMR) our répondre aux questions suivantes, il faut noter que lorsqu'un acteur reçoit une récompense, le film en reçoit une indirectement. Ce schéma complémentaire conduit à utiliser une union dans les requêtes. Requête de difficulté moyenne Requête 24 : Donner le titre des films qui ont été primés au moins une fois (y compris les récompenses des acteurs jouant dans le film). orme plate SQL-89 : SELECT DISTINCT.TITRE,.ANNÉE, RÉCOMENSE_ILM R WHERE.NUM = R.NUM UNION SELECT DISTINCT.TITRE,.ANNÉE, RÉCOMENSE_ACTEUR RA WHERE.NUM = RA.NUM orme imbriquée SQL-92 : SELECT TITRE, ANNÉE WHERE NUM IN ( ROM RÉCOMENSE_ILM UNION ROM RÉCOMENSE_ACTEUR ) Requêtes difficiles Requête 25 : Lister les cinémas qui ont exclusivement passé des films primés. Il faut rephraser cette requête pour l exprimer de façon logique. La requête consiste à chercher les cinémas pour lesquels, quels que soient les films programmés, ces films ont obtenu au moins une récompense. Comme on ne peut pas utiliser d union dans une sous-requête, il faut donc utiliser une disjonction (ou). { cinéma : " film-programmé-dans-ce-cinéma ( ($ récompense-film tq film-aété-récompensé) ($ récompense-acteur tq film-a-été-récompensé) ) } Soit, après introduction d une double négation pour éliminer le ", la disjonction se transforme en conjonction (et) : Corrigé du TD SQL (BD-ilmographie) 13
{ cinéma : ÿ$ film-programmé-dans-ce-cinéma ( (ÿ$ récompense-film tq filma-été-récompensé) Ÿ (ÿ$ récompense-acteur tq film-a-été-récompensé) ) } orme imbriquée SQL-89 : SELECT NOM, VILLE ROM CINÉMA C WHERE NOT EXISTS ( ROM ASSE WHERE.NUMC = C.NUMC AND NOT EXISTS ( ROM RÉCOMENSE_ILM R WHERE R.NUM =.NUM ) AND NOT EXISTS ( ROM RÉCOMENSE_ACTEUR RA WHERE RA.NUM =.NUM ) ) En SQL-2 par contre, on peut utiliser une union dans une sous-requête, ce qui simplifie son expression. orme imbriquée SQL-92 prédicat NOT EXISTS : SELECT NOM, VILLE ROM CINÉMA C WHERE NOT EXISTS ( ROM ASSE WHERE.NUMC = C.NUMC AND NOT EXISTS ( ROM ( ROM RÉCOMENSE_ILM UNION ROM RÉCOMENSE_ACTEUR ) AS R WHERE R.NUM =.NUM ) ) orme imbriquée SQL-92 prédicat NOT IN : SELECT NOM, VILLE ROM CINÉMA WHERE NUMC NOT IN ( SELECT NUMC ROM ASSE WHERE NUM NOT IN ( SELECT R.NUM ROM ( ROM RÉCOMENSE_ILM UNION ROM RÉCOMENSE_ACTEUR ) AS R ) ) ) Requête 26 : Donner le titre des films qui ont reçu au moins trois récompenses. orme imbriquée SQL-92 : SELECT TITRE, ANNÉE WHERE NUM IN ( SELECT R.NUM ROM ( ROM RÉCOMENSE_ILM UNION ROM RÉCOMENSE_ACTEUR ) AS R GROU BY R.NUM HAVING COUNT (*) >= 3 ) Corrigé du TD SQL (BD-ilmographie) 14
Requête 27 : Noms et prénoms des acteurs qui ont reçu plus de récompenses qu'aucun acteur qui a joué dans "Casablanca" n'en a eu. orme imbriquée SQL-92 : SELECT RÉNOM, NOM SELECT NUMA ROM RÉCOMENSE_ACTEUR GROU BY NUMA HAVING COUNT (*) > ( SELECT MAX ( SELECT COUNT (*) ROM RÉCOMENSE_ACTEUR WHERE NUMA IN ( SELECT NUMA ROM DISTRIBUTION WHERE NUM IN ( WHERE TITRE = Casablanca ) ) GROU BY NUMA ) ) ) Corrigé du TD SQL (BD-ilmographie) 15