Voici une manière typique de faire cette requête sans utiliser la méthode de sous-requête que vous avez montrée. Cela peut satisfaire la demande de @Godeke de voir une solution basée sur la jointure.
SELECT *
FROM movies m
LEFT OUTER JOIN seen s
ON (m.id = s.movie_id AND s.user_id = 123)
WHERE s.movie_id IS NULL;
Cependant, dans la plupart des marques de base de données, cette solution peut être moins performante que la solution de sous-requête. Il est préférable d'utiliser EXPLAIN pour analyser les deux requêtes, pour voir laquelle fonctionnera le mieux compte tenu de votre schéma et de vos données.
Voici une autre variante de la solution de sous-requête :
SELECT *
FROM movies m
WHERE NOT EXISTS (SELECT * FROM seen s
WHERE s.movie_id = m.id
AND s.user_id=123);
Il s'agit d'une sous-requête corrélée, qui doit être évaluée pour chaque ligne de la requête externe. Cela coûte généralement cher et votre exemple de requête d'origine est meilleur. D'autre part, dans MySQL "NOT EXISTS
" est souvent meilleur que "column NOT IN (...)
"
Encore une fois, vous devez tester chaque solution et comparer les résultats pour être sûr. C'est une perte de temps de choisir une solution sans mesurer les performances.