[SQL] Problème de LEFT JOIN

Explication du problème:

J’ai une table produit qui contient X produits (exemple: boulons, vis, mais aussi perceuses, donc aussi bien des éléments de machines que des machines elles mêmes). Le but est de sortir une liste de tous les produits, avec leur prix de vente, et la somme des prix de vente des produits les constituants (par exemple, une perceuse contient 15 vis). J’ai une table qui me permet de faire la jointure (construction, avec id_prod, id_prod_requis, quantité, type d’activité, qui peut être “construire”, ou “démonter”). Dans le cas qui m’interresse, je veux juste les couts associés à construire.

Le problème est que certains produits n’ont pas de produit les constituant (par exemple une vis) donc j’aimerais que le prix du produit constituant soit égal à NULL. Je me dis, pas de problème, on va utiliser LEFT JOIN. Mais en fait il ya trop de jointures et je m’y perds un peu…

Structures des tables:

vente AS vente_dest: information de vente du produit de destination (contient id_prod, mais aussi le prix de vente public du produit, ainsi que le prix d’achat)
prod AS prod_dest: information du produit de destination

vente AS vente_source: information de vente du produit source (contien id_prod, mais aussi le prix de vente public du produit, ainsi que le prix d’achat)
prod AS prod_source: information du produit source

activite: contient une liste des activité disponibles (actuellement, construire, démonter, remplacer une pièce).

construction: contient id_prod, id_prod_requis, qtt, et id_activite

Problème

En fait j’avais trouvé la jointure jusqu’à la table construction, mais après je ne sais pas si les tables ‘sources’ doivent être dans le LEFT JOIN ou pas:

SELECT * FROM vente AS vente_dest, prod AS prod_dest LEFT JOIN construction ON construction.id_prod = prod_dest.id WHERE vente_dest.id_prod = prod_dest.id

Jusque là, ca fonctionne (construction est bien a NULL pour les id produits qu’on n’ont pas d’infos de construction). Seulement je ne sais pas comment rattacher mes tables activite, vente_source et prod_source (sachant qu’ensuite je dois faire un GROUP BY prod_dest.id pour avoir la SUM des prix constituant le produit)

Alors, any idea?

edit: je tournes avec Mysql 4.1

pas le temps de regarder de près pour l’instant, mais tu peux faire des sous requêtes du style :

select bla bla from( (Table1 inner join Table2) left join (table 3 inner join table4) ) group by bla bla

C’est quoi ta base de données ?

Je verrais bien une petite solution avec des bouts d’UNION dedans, genre :

SELECT la liste des produits qui n’apparaissent pas dans la table construction avec l’activité constuire avec une valeur NULL dans la colonne du prix des pièces
UNION
SELECT les produits avec des pièces qui leur servent pour la construction avec le GROUP BY qui va bien comme l’a dit Phili_B pour calculer la somme des prix des pièces

Si tu veux le détail de la requête je peux te le donner, mais je pense que tu dois pouvoir trouver ca tout seul.

Par contre, il y a un détail que tu n’as pas spécifié : le calcul du prix des pièces composantes ne doit pas être récursif j’espère ? Je m’explique :
Si il faut 5 bidules a 5 € pour faire une perceuse à 50€ et qu’il faut 4 vis à 1€ pour faire un bidule à 5€, la somme des prix des composants de la perceuse doit il apparaitre comme la somme des bidules (soit 5x5) ou bien la somme des prix des vis ? (soit 5x4x1) ?

La solution que je t’ai donnée répond au premier cas.

Eh nan, il n’a pas besoin d’etre récursif pour la simple et bonne raison que:

Tu prends un moteur, il a les pièces rotor et ame (si je me rappelles bien). Ces deux pièces séparés constituent le prix du moteur, que tu vas revendre a un autre prix (qui servira au prix de base de la perceuse) etc… chaque produit dispose d’un prix de vente propre :P.

UNION pourrait fonctionner je vais faire quelques tests (j’y avais pas pensé en fait), mais euh on peut faire des GROUP BY sur des UNION? Oubliez c’est une connerie…

Je capte pas tous ton probleme mais un truc dans le genre ->

SELECT v.produit, v.prix, SUM (p.qtt*p.prix)
FROM vente v, produit p
WHERE v.id_prod = p.id

En fait ca me parait un peu trop simple comme solution pour etre bonne :s

Trouvé la solution:

[code](
SELECT

finished_inv.typeName,
finished_prod.buy_price,
SUM(required_prod.sell_price * tl2materialsfortypewithactivity.quantity) / finished_inv.portionSize AS prod_price,
finished_prod.sell_price

FROM

incorporated.product AS finished_prod,
incorporated.product AS required_prod,
eve_static_data.invtypes AS finished_inv,
eve_static_data.invtypes AS required_inv,
eve_static_data.activity,
eve_static_data.tl2materialsfortypewithactivity

WHERE

finished_prod.id_eve_static_data_invtypes = finished_inv.typeID AND
required_prod.id_eve_static_data_invtypes = required_inv.typeID AND
tl2materialsfortypewithactivity.activity = activity.id AND
tl2materialsfortypewithactivity.requiredTypeID = required_inv.typeID AND
tl2materialsfortypewithactivity.typeID = finished_inv.typeID AND
activity.name = “ReverseEngineer”

GROUP BY

finished_inv.typeName
)

UNION

(
SELECT

finished_inv.typeName,
finished_prod.buy_price,
NULL AS prod_price,
finished_prod.sell_price

FROM

incorporated.product AS finished_prod,
eve_static_data.invtypes AS finished_inv

WHERE

finished_prod.id_eve_static_data_invtypes = finished_inv.typeID AND
NOT EXISTS(SELECT * FROM eve_static_data.tl2materialsfortypewithactivity WHERE tl2materialsfortypewithactivity.typeID = finished_inv.typeID)
)

ORDER BY typeName[/code]

Bon ben ca me reparais trop simple :s

Select *
From a
where a.id <> ANY (select id
from B )

voir peut etre :

select *
from a, b
where a.id <>b.id

la 1er devrait aller la 2eme je sais pas