Requete sql

donc voilà mon problème:
la structure de la base (simplifié) est la suivante

table fapf0
fa0001 (pk), not null
fa0041, null

table fkpf0
PrimaryKey
fk0001 (fk -> fa0001), not null
fk0301, null
fk0102, not null

table adpf0
PrimaryKey
ad0001 (fk -> fa0001), not null
ad0100, not null
ad0210, null

on me donne 4 ID

ID1=fkpf0.fk0301 quand fkpf0.fk0102=120
ID2=fapf0.fa0041
ID3=fkpf0.fk0301 quand fkpf0.fk0102=140
ID4=fkpf0.fk0301 quand fkpf0.fk0102=800

et un code postal

CP=adpf0.ad0210 quand adpf0.ad0100=1

je cherche une requete pour me sortir les fapf0.fa0001 où
soit j’ai 2 IDs de juste OU 1 ID de juste et et le CP.
Je suis un peu perdu là.

Les noms des éléments de tes tables sont d’un clair… T’as pas des noms plus lisibles? Je suis sûr que déjà ça t’aiderait, et nous aussi :stuck_out_tongue:

Tous les champs (exceptés la pk et les 2 fk si je ne m’abuse) peuvent etre NULL?

+1 avec cold et je comprends pas trop ton histoire d’ID…

ID1=fkpf0.fk0301 quand fkpf0.fk0102=120 => ca veut dire que fk0301 doit etre renseigner quand fkpf0.fk0102=120 ? ou il faut juste que fkpf0.fk0102=120 existe (dans ce cas la fkpf0.fk0301 on s’en fou)?? bref c’est pas claire .

Et tes pk sur les autres tables?

[quote name=‹ azacreel2 › date=’ 20 Dec 2004, 11:26’]+1 avec cold et je comprends pas trop ton histoire d’ID…

ID1=fkpf0.fk0301 quand fkpf0.fk0102=120 => ca veut dire que fk0301 doit etre renseigner quand fkpf0.fk0102=120 ? ou il faut juste que fkpf0.fk0102=120 existe (dans ce cas la fkpf0.fk0301  on s’en fou)?? bref c’est pas claire .

Et tes pk sur les autres tables?
[right][post=« 314814 »]<{POST_SNAPBACK}>[/post][/right][/quote]

Pas de pk sur les autres tables mais des foreign keys, donc si je me souviens bien de mes cours de SQL, ses fk prennent la valeur du pk correspondant de la 1e table. Mais je me souviens pas bien du tout de mes cours de sql (pourtant j’en ai bouffé à l’époque), donc je dis sûrement une connerie :stuck_out_tongue:

Edit: et ce que j’aime, c’est qu’il a donné les tables « simplifiées » :stuck_out_tongue:

[quote name=‹ ColdFire › date=’ 20 Dec 2004, 11:32’]Pas de pk sur les autres tables mais des foreign keys, donc si je me souviens bien de mes cours de SQL, ses fk prennent la valeur du pk correspondant de la 1e table. Mais je me souviens pas bien du tout de mes cours de sql (pourtant j’en ai bouffé à l’époque), donc je dis sûrement une connerie :stuck_out_tongue:

Edit: et ce que j’aime, c’est qu’il a donné les tables « simplifiées » :stuck_out_tongue:
[right][post=« 314818 »]<{POST_SNAPBACK}>[/post][/right][/quote]

ah non, avec une fk par rapport à une autre table tu as un rapport de 1 → n :stuck_out_tongue:

ID1=fkpf0.fk0301 quand fkpf0.fk0102=120

veut dire si pour une companie donnée (fapf0.fa0001) on a une entrée dans fkpf0 avec fk0102=120, alors on devrait avoir l’ID1 dans fk0301.

genre

companie A, fapf0.fa0001=007

on devrait avoir dans fkpf0
fkpf0.fk0001=007
fkpf0.fk0102=120
fkpf0.fk0301=ID1

si on a
fkpf0.fk0001=007
fkpf0.fk0102=999 (en gros pas 120)
fkpf0.fk0301=ID1

on s’en fout.

J’ai beau faire des requêtes toute la journée, avec des noms pareils, je suis complètement largué là :stuck_out_tongue:

Et je confirme au fait: une foreign qui ne peut logiquement pas avoir valeur de primary, car sinon ce serait un rapport 1,1, et donc une erreur de conception de la base.

là j’ai un truc du type

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

bon là ca fait 11 minutes que ca tourne alos que ca ne devrait rien retourner en résultat car,
select fk0001 from fkpf0 where (fk0102=800 and fk0301=‹ 535-000211 ›) or (fk0102=120 and fk0301=‹ 7750000918 › ) → rien
select fa0001 from fapf0 where fa0041=‹ RPP10 › → rien

p’tain les noeuds au cerveau :stuck_out_tongue:

bon, je comprends beaucoup mieux avec ton explication Gynsu. Si ta pas de réponse d’ici cet aprèm, j’essaye (la je vais miam :stuck_out_tongue: )

bien sur qu’une primary key peut etre une foreign key c’est pour les liaison 1,n 1,n par exemple.

Par contre Gynsu2000, j’ai toujours pas compris ta table (elle me fait mal aux yeux). Si tu pouvais mettre des vrai noms se serait bien plus clair (ou alors un ptit schema relationnel des familles) pour pouvoir t’aider.

[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 :stuck_out_tongue:

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 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(un ID parmi les ID1 ID2 ID3 ID4 ET CP) ORDER BY fa0001; &nbsp; //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 :stuck_out_tongue:

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 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AND ( // C'est parti pour les conditions à la chaine &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ( // première partie, deux ID au choix &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ( (FK.fk0301=ID1 AND FK.fk0102=120) //ID1 ET ID2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AND (FA.fa0041=ID2) ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OR ( (FK.fk0301=ID1 AND FK.fk0102=120) //ID1 ET ID3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AND (FK.fk0301=ID3 AND FK.fk0102=140) ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OR ( (FK.fk0301=ID1 AND FK.fk0102=120) //ID1 ET ID4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AND (FK.fk0301=ID4 AND FK.fk0102=800) ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OR ( (FA.fa0041=ID2) //ID2 ET ID3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AND (FK.fk0301=ID3 AND FK.fk0102=140) ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OR ( (FA.fa0041=ID2) //ID2 ET ID4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AND (FK.fk0301=ID4 AND FK.fk0102=800) ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OR ( (FK.fk0301=ID3 AND FK.fk0102=140) //ID3 ET ID4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;AND (FK.fk0301=ID4 AND FK.fk0102=800) ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) &nbsp;OR ( // deuxième partie : un CP et un ID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;(AD.ad0210=CP AND AD.ad0100=1) // Le CP &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND ( // ET... un ID au choix &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (FK.fk0301=ID1 AND FK.fk0102=120) //ID1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OR (FA.fa0041=ID2) //ID2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OR (FK.fk0301=ID3 AND FK.fk0102=140) //ID3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OR (FK.fk0301=ID4 AND FK.fk0102=800) // ID4 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) // fin de l'ID au choix &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) // fin de la deuxième partie &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ) //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, &nbsp; &nbsp; &nbsp; &nbsp; ID1 AS (SELECT fk0001 &nbsp; &nbsp;// Ici on définit les tables temporaires &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; FROM fkpf0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;WHERE fk0301=ID1 AND fk0102=120), &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ID2 AS blablabla &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ID3... etc jusqu'à CP, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;WHERE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;( (fa0001 IN ID1) AND (fa0001 IN ID2) ) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; OR &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 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 :stuck_out_tongue:

[quote name=‹ azacreel2 › date=’ 20 Dec 2004, 11:35’]ah non, avec une fk par rapport à une autre table tu as un rapport de 1 → n :stuck_out_tongue:
[right][post=« 314821 »]<{POST_SNAPBACK}>[/post][/right][/quote]

ah oui c’est vrai

je disais avec raison que je pouvais me planter :stuck_out_tongue:

Edit: orthographe, y’a pas de t à vrai :stuck_out_tongue:

euhh j’ai un gros doute sur les condition susposé la. Par exemple tu ecrit ca

OR ( (FK.fk0301=ID1 AND FK.fk0102=120) //ID1 ET ID3 AND (FK.fk0301=ID3 AND FK.fk0102=140) )

de visu tu ne retournera jamais rien, il faut au moment de la declaration doubler ta table et refaire les conditions. Ca donnerai :

SELECT fa0001 FROM fapf0 FA, fkpf0 FK , fkpf0 FK2, adpf0 AD // on renomme les tables, c'est plus lisible WHERE (FA.fa0001=FK.fk0001) AND (FA.fa0001=FK2.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 (FK2.fk0301=ID3 AND FK2.fk0102=140) ) OR ( (FK.fk0301=ID1 AND FK.fk0102=120) //ID1 ET ID4 AND (FK2.fk0301=ID4 AND FK2.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 (FK2.fk0301=ID4 AND FK2.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;

Apres faut tester ca et corriger en fonction.

Autrement c’est vrai que la 2 eme solutions est beaucouop plus propre/maintenable.

edit parenthese

[quote name=‹ azacreel2 › date=’ 20 Dec 2004, 14:33’]euhh j’ai un gros doute sur les condition susposé la. Par exemple tu ecrit ca

&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;OR ( (FK.fk0301=ID1 AND FK.fk0102=120) //ID1 ET ID3 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; AND (FK.fk0301=ID3 AND FK.fk0102=140) )

de visu tu ne retournera jamais rien[…]
[right][post=« 314888 »]<{POST_SNAPBACK}>[/post][/right][/quote]

Houla oui, complètement exact ! Je m’emballe je m’emballe et puis j’écris des énormités :stuck_out_tongue:
Merci pour la correction.

Bon merci beaucoups, j’ai suis arrivé à peu prés au meme résultat (avec des join) mais vu les conditions je pense pas que je puisse m’en sortir juste avec des requetes.
Je vais faire une petite applis vb pour gérer la chose ca sera plus simple (parce que là j’ai un peu perdu 1/2 journée pour un truc à finir avant noel).
Encore merci à tous!

mais ce sont les vrais noms!

dommage, c’etait marrant comme jeux :stuck_out_tongue: