[quote name=‹ Gynsu2000 › date=’ 20 Dec 2004, 11:44’]select fa0001 from fapf0 c, fkpf0 i, adpf0 a where (i.fk0102=800 and i.fk0301=‹ 535-000211 › and c.fa0001=i.fk0001) or (i.fk0102=120 and i.fk0301=‹ 7750000918 › and c.fa0001=i.fk0001) or (c.fa0001=a.ad0001 and a.ad0100=1 and a.ad0210=‹ 99300 ›) or c.fa0041=‹ RPP10 › and order by c.fa0001
[right][post=« 314829 »]<{POST_SNAPBACK}>[/post][/right][/quote]
Déjà tu supprimes ce « and » et tu vas à la ligne avant ton ORDER BY. Fais des requêtes claires et un minimum indentées, le SQL c’est comme n’importe quel code, si c’est pas propre c’est illisible 
Bon, ta requête si je comprends bien c’est du genre :
SELECT fa0001
FROM fapf0
WHERE (deux ID parmi les ID1 ID2 ID3 ID4
OR
(un ID parmi les ID1 ID2 ID3 ID4 ET CP)
ORDER BY fa0001; //Ca c'est le petit plus :p
Je vais essayer de détailler le truc petit à petit, ca va m’aider à y voir plus clair aussi parce que les noms sont pas top intuitifs 
Bon, on utilise que 3 tables, donc on va pas chier des pendules, d’entrée on fait une jointure interne sur les 3 tables en utilisant les FK. En plus je sais pas si ton SGBD gère les requêtes imbriquées… bref, faisons simple.
SELECT fa0001
FROM fapf0 FA, fkpf0 FK, adpf0 AD // on renomme les tables, c’est plus lisible
WHERE (FA.fa0001=FK.fk0001) AND (FA.fa0001=AD.ad0001) // conditions de jointure
Voilà, ca nous donne une bonne base pour bosser, maintenant on peut passer au plat de résistance, les conditions sur les ID et le Code Postal !
On s’embete pas, 2 ID parmis les 4 ca veut dire :
(ID1 AND ID2) OR (ID1 AND ID3) OR (ID1 AND ID4) OR (ID2 AND ID3) OR (ID2 AND ID4) OR (ID3 AND ID4).
On peut très bien factoriser et mettre des (ID1 AND (ID2 OR ID3 OR ID4) etc… avec des parenthèses de partout, mais là encore, restons simples.
Pour le code postal et un ID, c’est plus facile :
(CP AND (ID1 OR ID2 OR ID3 OR ID4) ).
Comme on a une méga jointure de toutes les tables, c’est facile d’exprimer les IDx en contraintes, ca va filtrer le tout et on ne va guarder que les bons résultats (logiquement).
Allez, c’est parti pour la requête finale (et à toujours en écrire des tonnes y’en aura un qui va poster une réponse en 3 lignes avant moi) :
SELECT fa0001
FROM fapf0 FA, fkpf0 FK, adpf0 AD // on renomme les tables, c'est plus lisible
WHERE (FA.fa0001=FK.fk0001) AND (FA.fa0001=AD.ad0001) // conditions de jointure
AND ( // C'est parti pour les conditions à la chaine
( // première partie, deux ID au choix
( (FK.fk0301=ID1 AND FK.fk0102=120) //ID1 ET ID2
AND (FA.fa0041=ID2) )
OR ( (FK.fk0301=ID1 AND FK.fk0102=120) //ID1 ET ID3
AND (FK.fk0301=ID3 AND FK.fk0102=140) )
OR ( (FK.fk0301=ID1 AND FK.fk0102=120) //ID1 ET ID4
AND (FK.fk0301=ID4 AND FK.fk0102=800) )
OR ( (FA.fa0041=ID2) //ID2 ET ID3
AND (FK.fk0301=ID3 AND FK.fk0102=140) )
OR ( (FA.fa0041=ID2) //ID2 ET ID4
AND (FK.fk0301=ID4 AND FK.fk0102=800) )
OR ( (FK.fk0301=ID3 AND FK.fk0102=140) //ID3 ET ID4
AND (FK.fk0301=ID4 AND FK.fk0102=800) )
) OR ( // deuxième partie : un CP et un ID
(AD.ad0210=CP AND AD.ad0100=1) // Le CP
AND ( // ET... un ID au choix
(FK.fk0301=ID1 AND FK.fk0102=120) //ID1
OR (FA.fa0041=ID2) //ID2
OR (FK.fk0301=ID3 AND FK.fk0102=140) //ID3
OR (FK.fk0301=ID4 AND FK.fk0102=800) // ID4
) // fin de l'ID au choix
) // fin de la deuxième partie
) //fin de toutes les conditions
ORDER BY fa0001;
OK, c’est limite goretissimo et c’est long comme le bras, mais ca tient en une requête sans SELECT imbriqués.
La solution la plus élégante serait de faire 5 VUES contenant les résultat des requêtes sur les ID et le CP, ou à la rigueur de les utiliser dans des requêtes imbriquées ou bien dans des tables temporaires , c’est à dire les déclarer dans le FROM quoi, ca évite les VUES mais c’est pas tous les SGBD qui autorisent ca.
Les tables temporaires ca donne à peu près un truc genre (à vérifier) :
SELECT fa0001
FROM fapf0 FA,
ID1 AS (SELECT fk0001 // Ici on définit les tables temporaires
FROM fkpf0
WHERE fk0301=ID1 AND fk0102=120),
ID2 AS blablabla
ID3... etc jusqu'à CP,
WHERE
( (fa0001 IN ID1) AND (fa0001 IN ID2) )
OR
etc.
C’est plus élégant et on ne calcule tout ca qu’une fois (en théorie).
Si le SGBD n’accepte pas les déclaration de tables temporaires, tu replaces les tables ID1…CP dans la requête par leur définition donnée dans le FROM. Par contre comme tu utilises des IN fais bien gaffe à ce que tes SELECT imbriqués renvoient exactement le même type d’attribut que fa0001 (mais comme tu ne renvoies que des FK qui pointent sur fa0001 y’a pas de lézard).
A toi de voir donc en fonction des possibilités de ton SGBD.
J’espère avoir à peu près compris ton problème quand même, et si je suis tombé à coté ou si la requête ne marche pas (ce qui est fort possible vu le nombre de parenthèses !) j’espère que ca va t’aider un minimum 