J'ai cette requête MySQL:
ID MovieID GenreID ====================== 924 271 8
Cela renvoie le jeu d'enregistrements suivant:
select * from Movies_Genres where MovieID = 271 and GenreID <> 13
Movies_Genres est une table union / jonction avec des relations plusieurs-plusieurs .
Maintenant, si j'exécute cette requête légèrement modifiée:
ID MovieID GenreID ====================== 924 271 8 1251 271 13
I récupérez le jeu d'enregistrements suivant:
select * from Movies_Genres where MovieID = 271
Jusqu'ici tout va bien. Mais ce que j'essaie de réaliser, c'est d'avoir 0 enregistrement renvoyé pour cette deuxième requête si le film a un GenreID associé de 13 . Donc, le fait que dans ma requête ci-dessus le film a des genres liés de 13 ET 8, je veux que 0 enregistrement soit renvoyé parce que le film a un GenreID de 13. S'il avait un GenreID de, disons, 8, 1 et 2 - alors Je voudrais que 3 enregistrements soient retournés. S'il avait un GenreID de seulement 13, je voudrais que 0 enregistrement soit renvoyé - ce qu'il fait déjà correctement. Pour résumer: Tout film avec un GenreID associé de 13 ne doit jamais renvoyer aucun enregistrement, même s'il a également d'autres GenreID liés .
Comment cela peut-il être réalisé?
3 Réponses :
Une option implique l'agrégation:
SELECT mg.*
FROM Movies_Genres mg
WHERE mg.MovieID NOT IN (SELECT MovieID FROM Movies_Genres GROUP BY MovieID
HAVING COUNT(CASE WHEN GenreID = 13 THEN 1 END) > 0);
La requête ci-dessus est quelque peu triviale, car elle renverrait tout au plus un seul MovieID , 271 code >, s'il n'avait pas le genre 13 associé. Si vous voulez trouver les enregistrements complets, nous pouvons essayer:
SELECT MovieID FROM Movies_Genres WHERE MovieID = 271 GROUP BY MovieID HAVING COUNT(CASE WHEN GenreID = 13 THEN 1 END) = 0;
Peut-être avez-vous besoin d'un groupe avec
select *
from Movies_Genres
group by MovieId having count(GenreID=13) =0
Si vous voulez les enregistrements originaux, alors n'existe pas semble approprié:
select mg.MovieID, group_concat(mg.GenreID) as genreids from Movies_Genres mg group by mg.MovieID having sum( mg2.GenreID = 13 ) = 0;
Si vous voulez juste les films plutôt que le genreID code > détails, vous pouvez utiliser group by :
select mg.MovieID from Movies_Genres mg group by mg.MovieID having sum( mg2.GenreID = 13 ) = 0;
En fait, vous pouvez ajouter les identifiants de genre sous forme de liste dans ce cas: p >
select mg.*
from Movies_Genres mg
where not exists (select 1
from movies_genres mg2
where mg2.MovieID = mg.MovieID and
mg2.GenreID = 13
);
ayant sum (mg2.GenreID = 13) attribuera genreId à 13 fonctionnera même si j'ai essayé de la même manière similaire à ce que count (..)
@HimanshuAhuja. . . Hein? Je ne comprends vraiment pas votre commentaire. L'expression sum (mg.GenreID = 13) compte le nombre de fois que genreId est égal à 13. Le = 0 indique qu'il n'y a pas de telles lignes pour le film.
c'est ce que j'ai dit, c'est une façon correcte de faire fonctionner l'agrégation pour éviter d'écrire la même colonne en groupe par
Cela semble très prometteur mais je ne peux pas ajouter ma commande par: ORDER BY RAND () - cela jette une erreur sur le order by
@HerrimanCoder. . . Pourquoi ne pouvez-vous pas ajouter order by rand () ? Cela devrait aller juste après la clause ayant .
PEBKAC - J'avais un point-virgule errant. Merci a tous.