1
votes

Exclure les documents connexes - culpabilité par association

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é?


0 commentaires

3 Réponses :


0
votes

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;


0 commentaires

0
votes

Peut-être avez-vous besoin d'un groupe avec

        select * 
          from Movies_Genres 
          group by MovieId having count(GenreID=13) =0


0 commentaires

2
votes

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
                 );


6 commentaires

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.