requête NOT IN/NOT EXISTS

requête NOT IN/NOT EXISTS - SQL/NoSQL - Programmation

Marsh Posté le 02-10-2013 à 14:54:55    

bonjour,
 
Cela fait longtemps que je n'ai plus trop touché de SQL (MySQL ici) et je bloque sur une requête pourtant relativement simple dans l'idée.  
En effet, cela se présente comme suit.  
Soit 3 tables :
Groupe(ID_Groupe, Libelle_groupe,...)
Abonne(Mail, Nom, ...)
Appartenir (Mail,ID_Groupe)
 
Le but est de chercher, pour un utilisateur donné, la liste des groupes dont il ne fait pas partie.  
 
J'ai essayé de faire ceci :  

Code :
  1. SELECT DISTINCT Groupe.ID_Groupe FROM Groupe, Appartenir
  2. WHERE Groupe.ID_Groupe=Appartenir.ID_Groupe
  3. AND Mail = "unuser@adresse.fr"
  4. AND NOT EXISTS (SELECT * FROM Groupe);


 
Je me retrouve avec un résultat vide alors que j'attendais pour cet exemple "groupe 3" (l'abonné faisant partie du groupe 1 et groupe 2 dans mon petit jeu de tests)
 
Merci pour toute aide


Message édité par roswellentongues le 02-10-2013 à 14:57:26
Reply

Marsh Posté le 02-10-2013 à 14:54:55   

Reply

Marsh Posté le 02-10-2013 à 15:22:48    

Reply

Marsh Posté le 03-10-2013 à 04:33:30    

Connais pas MySQL mais je peux te le faire en Oracle, je suppute que c'est du SQL assez classique pour que ca marche pareil.

 

Deja, la tienne ne marche pas parce que ton (SELECT * FROM groupe) n'est pas "connecte" au reste, du coup il suffit qu'il y ait un groupe dans la table Groupe pour que le select retourne quelque chose, et du coup le NOT EXISTS va retourner "faux" (et donc ta requete ne retourne rien puisque le filtre renvoie toujours "faux" ).

 

T'as plusieurs manieres de faire:

SELECT g.id_groupe
FROM groupe g
WHERE NOT EXISTS (SELECT 1
                  FROM appartenir a
                  WHERE a.mail = "unuser@adresse.fr"
                    AND a.id_groupe = g.id_groupe);


SELECT g.id_groupe
FROM groupe g
WHERE id_groupe NOT IN (SELECT a.id_groupe
                        FROM appartenir a
                        WHERE a.mail = "unuser@adresse.fr" );


SELECT g.id_groupe
FROM groupe g
LEFT JOIN appartenir a ON a.id_groupe = g.id_groupe AND a.mail = "unuser@adresse.fr"
WHERE a.id_groupe IS NULL;


J'pense que la premiere est la plus "correcte".
La seconde avec le NOT IN parait que c'est pas le plus performant (sous Oracle en tout cas).
Perso je prefere la troisieme (question de gout) mais j'ai remarque que de mettre des filtres directement dans les jointures ca herisse certaines personnes, donc si c'est pour un exo vaut p'tetre mieux rester sur le NOT EXISTS des fois que ton prof soit pointilleux.


Message édité par lasnoufle le 03-10-2013 à 04:34:34

---------------
C'était vraiment très intéressant.
Reply

Marsh Posté le 03-10-2013 à 08:51:29    

[:shimay:1] Merci lasnoufle. Merci pour ton explication, j'ai compris où était mon erreur.
En fait, c'est pour créer une espèce de filtre en php. Le fait d'inscrire une personne dans un groupe et à chaque appel de page, ne faire apparaître que les groupes pour lesquels la personne à inscrire ne fait pas partie.


Message édité par roswellentongues le 03-10-2013 à 08:57:44
Reply

Marsh Posté le 03-10-2013 à 09:35:06    

en mysql, pour optimiser c'est la dernière qu'il faut prendre, et il me semble que beaucoup de SQL n'aiment pas trop les NOT IN justement. D'où mon lien qui donne la 3eme manière que tu as donné pour un équivalent à un not in.

Reply

Marsh Posté le 03-10-2013 à 16:54:44    

Pablo Escrobarbe a écrit :

en mysql, pour optimiser c'est la dernière qu'il faut prendre, et il me semble que beaucoup de SQL n'aiment pas trop les NOT IN justement. D'où mon lien qui donne la 3eme manière que tu as donné pour un équivalent à un not in.


En effet oui, en lisant ton lien, je regardais du côté du "left join" mais je cherchais où inclure le "a.mail = "unuser@adresse.fr"". :)


Message édité par roswellentongues le 03-10-2013 à 16:55:11
Reply

Marsh Posté le 05-11-2013 à 14:29:11    

select * from groupe as a              
where a.id_groupe not in              
(select b.id_groupe from              
appartient as b                        
inner  join abonne as c                
on b.mail= c.mail
where c.nom= ???           )  
Pourquoi, ne pas utilisier un Id_utilisateur, à la place de mail comme clé?
"Dénormaliser" juste pour ça ... est ce bien utile?
 
Guillaume


Message édité par gpl73 le 05-11-2013 à 14:34:51
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed