recherche de valeurs inexistantes

Eléphanteau du PHP | 14 Messages

27 mai 2005, 11:40

Bonjour,

J'ai un petit soucis concernant une requete qui devrait être toute simple pourtant.
J'ai trois tables :

organisation : idorg, nomorg, adresse

categorie : idcat, nomcat

et link : idlink, organisation, categorie


J'essaie de trouver une requete me permettant de retrouver les enregistrements de la table organisation qui n'ont pas de catégorie (qui ne sont donc pas reprise au moins une fois dans la table link)
j'ai essayé la requete suivante :

Code : Tout sélectionner

SELECT idorg FROM organisation WHERE idorg NOT IN (SELECT organisation from link)


il me met un code d'erreur à la ligne 5, donc juste après le IN
j'ai essayé en rajoutant un group by au second select aussi, mais ça ne change rien.

Est-ce que quelqu'un pourrait me dire d'où vient l'erreur ou me donner une autre solution?

Merci d'avance pour vos réponses et lectures
Doria

Eléphant du PHP | 406 Messages

27 mai 2005, 11:55

essai avec Not Exists

Invité
Invité n'ayant pas de compte PHPfrance

27 mai 2005, 12:06

Code : Tout sélectionner

SELECT * FROM organisation WHERE NOT EXISTS ( SELECT * FROM link WHERE link.organisation = organisation.idorg )
ça donne

Code : Tout sélectionner

#1064 - You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near 'EXISTS ( SELECT * ....
franchement je sèche là...

Eléphanteau du PHP | 14 Messages

27 mai 2005, 12:09

Oups, oublié de me logger au précédent message, sorry :p
Doria

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

27 mai 2005, 12:09

La clause WHERE compare un champ avec un autre, il faut donc que ta requete soit de la forme :

Code : Tout sélectionner

SELECT * FROM organisation WHERE champ1 NOT IN ( SELECT champ2 FROM link WHERE link.organisation = organisation.idorg )
Mais il faut que champ1 et champ2 soit des champs de même types
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

ViPHP
pjl
ViPHP | 2119 Messages

27 mai 2005, 12:20

1. il y a un pb de conception. Ce n'est pas normal qu'une table et qu'un champ d'une autre table porte le même nom.

2. pourquoi faire une requête imbriqué et non une jointure externe ?

Eléphanteau du PHP | 14 Messages

27 mai 2005, 12:21

bon je vous mets les vrais noms de champs, on sait jamais que ça puisse influencer :

Code : Tout sélectionner

SELECT * FROM organisation WHERE organisation.id NOT IN (SELECT organisation FROM link_organisation_categorie WHERE link_organisation_categorie.organisation = organisation.id)
link_organisation_categorie.organisation et organisation.id sont tous les deux de type int

pourtant il me donne toujours une erreur :
Doria

Eléphanteau du PHP | 14 Messages

27 mai 2005, 12:24

et bien j'ai essayé en changeant le nom du champ dans la table link. J'ai mis organisationid à la place de organisation :

Code : Tout sélectionner

SELECT * FROM organisation WHERE organisation.id NOT IN ( SELECT organisation FROM link_organisation_categorie WHERE link_organisation_categorie.organisationid = organisation.id
et ça me fait toujours pareil
Doria

Mammouth du PHP | 19672 Messages

27 mai 2005, 12:26

Attention, NOT IN n'est compris par MySQL qu'à partir de la version 4.1
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

ViPHP
pjl
ViPHP | 2119 Messages

27 mai 2005, 12:26

toutes les versions de MySQL n'acceptent pas ce type de requête, c'est pourquoi, je me repete, je préconise une jointure externe.

Eléphanteau du PHP | 14 Messages

27 mai 2005, 12:41

toutes les versions de MySQL n'acceptent pas ce type de requête, c'est pourquoi, je me repete, je préconise une jointure externe.
je le fais pour afficher les catégories liées à l'organisation :

Code : Tout sélectionner

SELECT categorieo.nom, organisation.nom FROM categorieo, organisation INNER JOIN link_organisation_categorie ON link_organisation_categorie.categorie = categorieo.id AND link_organisation_categorie.organisation = organisation.id
mais là je cherche à savoir quelles organisations ne sont pas linkées avec les catégories, et non savoir la catégorie correspondant à l'organisation

pour le not in ok, je suis à la version 4.0 donc normal.
Je reviens donc au point de départ :cry:
Doria

ViPHP
pjl
ViPHP | 2119 Messages

27 mai 2005, 12:49

attention, je parle de jointure externe, pas de jointure.

Administrateur PHPfrance
Administrateur PHPfrance | 11457 Messages

27 mai 2005, 12:52

attention, je parle de jointure externe, pas de jointure.
donc LEFT JOIN et link_organisation_categorie.organisation IS NULL (si j'ai bien tout suivi)

ViPHP
pjl
ViPHP | 2119 Messages

27 mai 2005, 13:01

A priori, oui.
A tester dans un client MySQL.
Et surtout virer le SELECT * et préciser les champs dont on a besoin.


Mais je suis sur qu'une rapide recherche sur "jointure externe" aurait apporté toutes les indication à Doria.

Eléphanteau du PHP | 14 Messages

27 mai 2005, 13:14

A priori, oui.
A tester dans un client MySQL.
Et surtout virer le SELECT * et préciser les champs dont on a besoin.


Mais je suis sur qu'une rapide recherche sur "jointure externe" aurait apporté toutes les indication à Doria.
En effet ça m'a permis de comprendre les jointures externes

donc j'ai finalement ça :

Code : Tout sélectionner

SELECT organisation.nom, organisation.id FROM organisation LEFT OUTER JOIN link_organisation_categorie ON link_organisation_categorie.organisation = organisation.id WHERE link_organisation_categorie.organisation IS NULL
merci pour votre aide :wink:
Doria