Bonjour à tous,
Je dois à tout prix faire en une seule requête une jointure entre 2 tables, mais je ne souhaite récupérer qu’une ligne de la seconde table même si plusieurs valeurs sont dispo (OK, c’est pas clair, un exemple devrait aider) :
Table 1 (t1) :
id valeur quantite
--------------------
1 v1 12
1 v1 3
2 v1 8
3 v2 37
...
Table 2 (t2) :
id valeur2
-----------
1 a1
1 a1
1 a2
1 a3
2 a2
...
Ce que je veux obtenir en recherchant l’id 1 :
id valeur valeur2 quantite
--------------------------
1 v1 a1 15
Note : Je veux ramener une seule valeur v2 (n’importe laquelle, toutes sont correctes)
C’est assez facile si on peut préciser l’id qu’on recherche (C’est pas beau, mais ça a le mérite de faire ce que je souhaite) :
select t1.id, t1.valeur, t2.valeur2, sum(t1.quantite) quantite
from t1, (select valeur2 from t2 where id='XXX' and rownum=1) t2 where t1.id = 'XXX'
group by t1.id, t1.valeur, t2.valeur2
Mais dans la pratique, je dois ramener un ensemble de valeurs id déduites d’autres colonnes de t1… Et le code précédent ne sert plus à rien
Quelqu’un a une idée?
Edité le 24/07/2007 à 18:42
Je comprends pas, avec un LEFT JOIN ça ne marcherait pas?
J’utilise LEFT JOIN pour ramener des éléments même si l’une des deux tables ne peut satisfaire la jointure (Ce qui n’est pas le cas ici)… On peut aussi l’utiliser pour faire ce genre de ‘tri’? Si tu peux être plus précis, je suis preneur
[quote="[myself]"]J’utilise LEFT JOIN pour ramener des éléments même si l’une des deux tables ne peut satisfaire la jointure (Ce qui n’est pas le cas ici)… On peut aussi l’utiliser pour faire ce genre de ‘tri’? Si tu peux être plus précis, je suis preneur
[/quote]
JOIN LEFT en effet s’utilise pour joindre deux tables, après il est obligatoire pour les tables sans jointure propre, mais personnelement je l’utilise aussi pour des jointures simples, ça evite d’avoir des erreurs SQL en cas d’erreurs dans la base de donnée.
Si j’ai bien compris, tu cherches à prendre une valeur dans la t2 pour la joindre à tous ta t1, seulement tu n’as besoin que d’une seule fois ce champ de la t2.
Après c’est surement pas beaux non plus, mais si tu fais ta requete du genre :
SELECT t1.id, t1.valeur, t2.valeur2, t1.quantite
FROM t1
LEFT JOIN t2 ON(t2.id=t1.id)
WHERE t1.id = 'XXX'
Qu’est-ce qui ne t’empêche pas, lors du traitement, de ressortir qu’une seule fois ta valeur de t2?
Genre :
while($data=mysql_fetch_assoc($req))
{
$valeur2=(!isset($data['valeur2']) || empty($data['valeur2']))?$data['valeur2']:$valeur2;
}
Et dans ce cas là même, est-ce que à chaque enregistrement la valeur2 va changer?
Y a quand même un truc faux là dedans…
“comment éviter le produit cartésien”
Une jointure, c’est un produit cartésien avec une condition pour éjecter des résultats hein
t’as tenté un truc genre (je suis pas sûr de mon coup)
SELECT
t1.id, t1.valeur, t1.quantite, (SELECT t2.valeur2 FROM t2 WHERE t2.id = t1.id AND rownum = 1)
FROM t1
?
Yep, je n’ai pas été assez précis
J’ai reprécisé un peu mon exemple (Ajout de sum + valeurs supplémentaires)
Dans la pratique j’ai toujours une valeur dans t2
La seule solution trouvée pour le moment est de faire un select dans le select (et non pas dans le from), ce qui me permet de faire la jointure entre les tables… Mais j’ai une vingtaine de champs à récupérer, soit une vingtaine de select à insérer… crade
– Edit
Sans-Nom -> Tu es retombé sur ce à quoi j’étais arrivé
Edité le 24/07/2007 à 17:56
Waouh, la requête de Sans-nom, une requête imbriquée sur les colonnes, j’avais encore jamais vu!
Faut dire que c’est pas focément efficace: Avec un group by: tu n’as droit qu’aux colonnes de regroupement et aux fonction d’agrégation: sum, min max… alors tu peux utiliser un min ou un max sur la colonne valeur2
vu que n’importe quelle valeur est utilisable, le max doit l’être.
select t1.id, t1.valeur, max(t2.valeur2), sum(t1.quantite) quantite from t1,t2
where <tout ce qu'on veut>
group by t1.id, t1.valeur
Edité le 24/07/2007 à 18:11
deltree > Solution interessante, je vais me tenter ça …
En plus, max marche aussi avec les VARCHAR
– Edit
Ca marche et sans exploser les coûts
Merci DarKChAm, Sans-Nom et deltree
Edité le 24/07/2007 à 18:42
Oui, ça n’a pas forcément la même signification un max sur varchar.