PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 21/01/2013 14:42:48

unisol
Membre

requete SELECT à 4 tables

bonjour,
j'ai une requete de ce type
//**
SELECT E1.id_entete_ot, E1.date_ot, E1.service, E2.nro_equipement, E2.designation, E2.nom_organe, E1.description, sum(O2.temps) as Temps, E2.id_equipement

FROM entete_ot E1 left outer join equipements E2 on (E1.id_equipement = E2.id_equipement)
left outer join ot O2 on (E1.id_entete_ot = O2.id_entete_ot) 

group by E1.id_entete_ot, E1.date_ot, E1.service, E2.nro_equipement, E2.designation, E2.nom_organe, E1.description, E2.id_equipement

//**

la colonne Temps est correctement calculée.

si je modifie la clause FROM comme ceci avec une requete à 4 tables :

//**
SELECT E1.id_entete_ot, E1.date_ot, E1.service, E2.nro_equipement, E2.designation, E2.nom_organe, E1.description, sum(O2.temps) as Temps, E2.id_equipement

FROM entete_ot E1 left outer join equipements E2 on (E1.id_equipement = E2.id_equipement)
left outer join ot O2 on (E1.id_entete_ot = O2.id_entete_ot) 
left outer join articles_ot A3 on (E1.id_entete_ot = A3.id_entete_ot)

group by E1.id_entete_ot, E1.date_ot, E1.service, E2.nro_equipement, E2.designation, E2.nom_organe, E1.description, E2.id_equipement

//**

la colonne Temps se voit démultiplié et renvoit une valeur incorrecte

le schema souhaité est :
pour une valeur E1 -> une valeur E2
pour une valeur E1 -> une ou plusieurs valeurs O2
pour une valeur E1 -> une ou plusieurs valeurs A3

merci pour votre aide.

Hors ligne

#2 21/01/2013 16:38:20

Marc Cousin
Membre

Re : requete SELECT à 4 tables

C'est à dire que vous avez la valeur multipliée par le nombre d'enregistrements de A3 liés à E1 ? C'est normal.

Que voulez-vous faire exactement ?

Dernière modification par Marc Cousin (21/01/2013 16:41:00)


Marc.

Hors ligne

#3 22/01/2013 00:35:42

unisol
Membre

Re : requete SELECT à 4 tables

bah, je souhaiterais une valeur qui ne soit pas démultiplié...

Hors ligne

#4 22/01/2013 08:22:08

Marc Cousin
Membre

Re : requete SELECT à 4 tables

En l'état, vu que vous n'utilisez pas les enregistrements de A3 dans la requête, ne le mettez tout simplement pas…

Après, ça dépend de ce que vous voulez vraiment faire des enregistrements de A3 dans le résultat final. Ce que vous souhaitez réellement, ça ne serait pas la jointure entre

SELECT E1.id_entete_ot, E1.date_ot, E1.service, E2.nro_equipement, E2.designation, E2.nom_organe, E1.description, sum(O2.temps) as Temps, E2.id_equipement
FROM entete_ot E1 left outer join equipements E2 on (E1.id_equipement = E2.id_equipement)
left outer join ot O2 on (E1.id_entete_ot = O2.id_entete_ot)
group by E1.id_entete_ot, E1.date_ot, E1.service, E2.nro_equipement, E2.designation, E2.nom_organe, E1.description, E2.id_equipement

et A3 ?

si oui, écrivez tout simplement:

SELECT *
FROM
  (SELECT E1.id_entete_ot,
          E1.date_ot,
          E1.service,
          E2.nro_equipement,
          E2.designation,
          E2.nom_organe,
          E1.description,
          sum(O2.temps) AS Temps,
          E2.id_equipement
   FROM entete_ot E1
   LEFT OUTER JOIN equipements E2 ON (E1.id_equipement = E2.id_equipement)
   LEFT OUTER JOIN ot O2 ON (E1.id_entete_ot = O2.id_entete_ot)
   GROUP BY E1.id_entete_ot,
            E1.date_ot,
            E1.service,
            E2.nro_equipement,
            E2.designation,
            E2.nom_organe,
            E1.description,
            E2.id_equipement) AS tmp1
LEFT JOIN articles_ot A3 ON (tmp1.id_entete_ot = A3.id_entete_ot)

Dernière modification par Marc Cousin (22/01/2013 08:23:54)


Marc.

Hors ligne

#5 22/01/2013 09:29:31

unisol
Membre

Re : requete SELECT à 4 tables

En effet j'ai ommis d'ajouter l'utilisation de A3
voici ce que je souhaiterais
*//
SELECT
   E1.id_entete_ot, E1.date_ot, E1.service, E2.nro_equipement, E2.designation, E2.nom_organe, E1.description,
   sum(O2.temps) as Temps,
   sum(O2.temps * O2.cout_pe) as Cout_MO,
   sum(A3.dpa * A3.quantite) as Cout_pieces,
   sum(O2.temps * O2.cout_pe) + sum(A3.dpa * A3.quantite) as Cout_Total,
   E2.id_equipement
FROM
   entete_ot E1 left outer join equipements E2 on (E1.id_equipement = E2.id_equipement)
   left outer join ot O2 on (E1.id_entete_ot = O2.id_entete_ot) 
   left outer join articles_ot A3 on (E1.id_entete_ot = A3.id_entete_ot)
group by
   E1.id_entete_ot, E1.date_ot, E1.service, E2.nro_equipement, E2.designation, E2.nom_organe, E1.description, E2.id_equipement
*//
pour être complet dans, il se peut, que par exemple des valeurs n'existes pas :
sum(A3.dpa * A3.quantite) as Cout_pieces, -> renvoi NULL
sum(O2.temps * O2.cout_pe) -> = 50
ce qui a pour effet de ne pas additionner
sum(O2.temps * O2.cout_pe) + sum(A3.dpa * A3.quantite) as Cout_Total,
50 + NULL = NULL
comment solutionner cette partie ?

merci par avance,

Dernière modification par unisol (22/01/2013 09:39:54)

Hors ligne

#6 22/01/2013 09:33:42

Marc Cousin
Membre

Re : requete SELECT à 4 tables

Vous n'avez pas A3 du tout dans les colonnes du SELECT. Ne le mettez donc pas dans la liste des tables à joindre dans ce cas.


Marc.

Hors ligne

#7 22/01/2013 09:46:26

unisol
Membre

Re : requete SELECT à 4 tables

vous avez publié un post apres moi,
si, je souhaite en effet utiliser A3, j'avais ommis  de l'ajouter dans ma requete.

Hors ligne

#8 22/01/2013 09:53:48

Marc Cousin
Membre

Re : requete SELECT à 4 tables

SELECT tmp1.*,  sum(A3.dpa * A3.quantite) as Cout_pieces
FROM
  (SELECT E1.id_entete_ot,
          E1.date_ot,
          E1.service,
          E2.nro_equipement,
          E2.designation,
          E2.nom_organe,
          E1.description,
          sum(O2.temps) AS Temps,
          E2.id_equipement
   FROM entete_ot E1
   LEFT OUTER JOIN equipements E2 ON (E1.id_equipement = E2.id_equipement)
   LEFT OUTER JOIN ot O2 ON (E1.id_entete_ot = O2.id_entete_ot)
   GROUP BY E1.id_entete_ot,
            E1.date_ot,
            E1.service,
            E2.nro_equipement,
            E2.designation,
            E2.nom_organe,
            E1.description,
            E2.id_equipement) AS tmp1
LEFT JOIN articles_ot A3 ON (tmp1.id_entete_ot = A3.id_entete_ot)
GROUP BY tmp1.id_entete_ot,
            tmp1.date_ot,
            tmp1.service,
            tmp1.nro_equipement,
            tmp1.designation,
            tmp1.nom_organe,
            tmp1.description,
            tmp1.id_equipement,
            tmp1.temps

Devrait fonctionner non ?


Marc.

Hors ligne

#9 22/01/2013 10:04:48

unisol
Membre

Re : requete SELECT à 4 tables

Nickel, merci ça marche !!!!
ma valeur n'est plus démultipliée.
encore une chose, avez vous une solution pour que mon addition se fasse, lorsque
une somme renvoi un null ?

Hors ligne

#10 22/01/2013 10:07:07

Marc Cousin
Membre

Re : requete SELECT à 4 tables

Il faut utiliser la fonction coalesce sur les valeurs NULL dans ce genre de cas:

coalesce(null,0) renvoie 0. Par exemple:
coalesce(sum(O2.temps * O2.cout_pe),0) + coalesce(sum(A3.dpa * A3.quantite),0) as Cout_Total


Marc.

Hors ligne

#11 22/01/2013 11:02:47

unisol
Membre

Re : requete SELECT à 4 tables

merci à vous marc,
je republie la requete au complet pour les autres..

**//

SELECT tmp1.*,  coalesce(sum(A3.dpa * A3.quantite),0) as Cout_pieces, tmp1.Cout_MO + coalesce(sum(A3.dpa * A3.quantite),0) as total
FROM
  (SELECT E1.id_entete_ot,
          E1.date_ot,
          E1.service,
          E2.nro_equipement,
          E2.designation,
          E2.nom_organe,
          E1.description,
          E2.id_equipement,
          coalesce(sum(O2.temps),0) AS Temps,
          coalesce(sum(O2.temps * O2.cout_pe),0) AS Cout_MO           
   FROM entete_ot E1
   LEFT OUTER JOIN equipements E2 ON (E1.id_equipement = E2.id_equipement)
   LEFT OUTER JOIN ot O2 ON (E1.id_entete_ot = O2.id_entete_ot)
where E1.date_ot between '01/01/2012' and '31/12/2012' and E1.service like 'ACCREDITATION QUALITE%' and E2.type_equipement like '%' and lower(E2.nom_organe) like '%' and lower(E2.designation) like '%'
   GROUP BY E1.id_entete_ot,
            E1.date_ot,
            E1.service,
            E2.nro_equipement,
            E2.designation,
            E2.nom_organe,
            E1.description,
            E2.id_equipement) AS tmp1
LEFT JOIN articles_ot A3 ON (tmp1.id_entete_ot = A3.id_entete_ot)
GROUP BY tmp1.id_entete_ot,
            tmp1.date_ot,
            tmp1.service,
            tmp1.nro_equipement,
            tmp1.designation,
            tmp1.nom_organe,
            tmp1.description,
            tmp1.id_equipement,
            tmp1.temps,
            tmp1.Cout_MO

Hors ligne

Pied de page des forums