Je travaille actuellement sur ceci https://cs50.harvard.edu/x/2020/psets/7/movies/ et j'essaie de terminer 9.sql.
Il existe une base de données appelée "films", avec des tableaux: films (colonnes: id, titre, année), personnes (id, nom, naissance) et stars (movie_id, person_id).
La tâche est:
écrivez une requête SQL pour répertorier les noms de toutes les personnes qui ont joué dans un film sorti en 2004, classés par année de naissance. Il doit renvoyer 18 013 noms.
Jusqu'à présent, voici ce que j'ai fait:
SELECT count(distinct name)
from people
join stars on stars.person_id = people.id
join movies on stars.movie_id = movies.id
WHERE year = 2004;
Cependant, cela ne renvoie qu'un décompte de 17965 ...
Quelqu'un peut-il voir pourquoi cela pourrait être?
Si vous count(distinct person_id)
, vous obtiendrez 18013. Il est raisonnable que le nom ne soit pas unique. Ce qui est déraisonnable, c'est la directive de l'examen disant que vous ne devez inscrire que le nom.
Une façon de distinguer correctement les noms est d'exécuter ceci:
SELECT p.name
from people p
where p.id in (
select distinct s.person_id
from stars s join movies m on s.movie_id = m.id
WHERE m.year = 2004)
Et si vous le faites de cette façon, vous n'avez même pas besoin de distinct
en raison de la définition de l'opérateur in
. Mais vous obtiendrez probablement le même plan d'exécution malgré tout.
Il est normal, à mon avis, de lister un p.name
plus d'une fois s'il appartient à une autre personne. La requête que vous avez écrite aurait été correcte si la règle commençait par ces mots:
Si le nom d'une personne ...
au lieu de ces mots:
Si une personne ...
Ce qui me rappelle quelque chose C. J. Date a fait en classe un jour. Il a mis une feuille sur son projecteur qui projetait l'image d'une pipe fumante sur le mur. Il a ensuite demandé: qu'est-ce que c'est?
Puisqu'il s'agissait d'une classe de base de données et non d'une classe de physique, personne n'osait être un smart-a **.