[ MySQL ] Requête imbriquée ???

Requête imbriquée ??? [ MySQL ] - SQL/NoSQL - Programmation

Marsh Posté le 06-03-2006 à 17:15:35    

Bonjour,
 
J'ai deux types de tables pour gérer mes stocks.
 
La table historique présente des lignes de 2 types (entrée/sortie) :
  hinat        hivar         hidte        hiqte
  char        char         date         int
- entree | varieteX | 22/02/06 | 150
- entree | varieteY | 22/02/06 | 1200
- sortie  | varieteX | 27/02/06 |  50
etc ...
 
La table stock présente des lignes d'un seul type (il s'agit du stock réel) :
stvar            stqte
char             int
varieteX   |  50
varieteY   |  1200
 
La théorie voudrait que pour chaque variété : historique.entree - historique.sortie = stock
 
Mais apparement j'ai des écarts.
Donc je souhaiterais afficher les variétés pour lesquelles j'ai des écarts.
 
Actuellement j'ai écris ça :


select stvar,stqte from stock  
where stvar!=
     ((select hiqte from historique where hivar=stvar and hinat='entree')
                        -   <--- soustraction
     (select hiqte from historique where hivar=stvar and hinat='sortie'));


 
Subquery returns more than a row :/
 
 
 
Toute aide est la bienvenue :jap:


Message édité par jeoff le 07-03-2006 à 11:02:31
Reply

Marsh Posté le 06-03-2006 à 17:15:35   

Reply

Marsh Posté le 06-03-2006 à 17:26:50    

les sous requetes c'est pas terrible terrible ...
 
Avec des jointures tu dois pouvoir t'en sortir. Quelque chose dans le genre:

Code :
  1. SELECT
  2. stvar,
  3. stqte,
  4. sum(coalesce(entree.qte,0)) - sum(coalesce(sortie.qte,0))
  5. FROM
  6.           stock
  7. LEFT OUTER historique entree ON ( entree.hivar = stvar AND entree.hinat='entree')
  8. LEFT OUTER historique sortie ON ( sortie.hivar = stvar AND sortie.hinat='sortie')
  9. GROUP BY
  10. stvar,
  11. stqte
  12. HAVING
  13. stqte= sum(coalesce(entree.qte,0)) - sum(coalesce(sortie.qte,0))

Message cité 1 fois
Message édité par anapajari le 06-03-2006 à 17:27:58
Reply

Marsh Posté le 06-03-2006 à 18:00:24    

anapajari a écrit :

les sous requetes c'est pas terrible terrible ...
 
Avec des jointures tu dois pouvoir t'en sortir. Quelque chose dans le genre:

Code :
  1. SELECT
  2. stvar,
  3. stqte,
  4. sum(coalesce(entree.qte,0)) - sum(coalesce(sortie.qte,0))
  5. FROM
  6.           stock
  7. LEFT OUTER JOIN historique AS entree ON ( entree.hivar = stvar AND entree.hinat='entree')
  8. LEFT OUTER JOIN historique AS sortie ON ( sortie.hivar = stvar AND sortie.hinat='sortie')
  9. GROUP BY
  10. stvar,
  11. stqte
  12. HAVING
  13. stqte= sum(coalesce(entree.qte,0)) - sum(coalesce(sortie.qte,0))



 
J'ai fait quelques modifs sur la syntaxe de la jointure.
Je connaissais mal le left outer join, ca à l'air assez puissant.
Par contre je n'ai pas compris à quoi sert la fonction coalesce ni dans les champs selectionné ni dans le having.
 
Pourrais-tu m'éclairer ? Merci ;)


Message édité par jeoff le 06-03-2006 à 18:02:37
Reply

Marsh Posté le 06-03-2006 à 18:07:48    

en fait coalesce ça remonte le premier element de la liste qui est non nul.
 
Si jamais une des jointures ne te remontes rien ( ou si une des valeurs est 'null') tu vas avoir tes sums qui seront nulles ( 1 + 3 + NULL = NULL) et pareil pour la différence.
C'est juste pour éviter ça que j'ai rajouté le coalesce...
 
note: il est possible que cela soit inutile sur certains sgbd!

Reply

Marsh Posté le 07-03-2006 à 11:02:02    

Après quelques essais, j'ai un problème.
 
Actuellement, l'historique ne compte qu'une et une seule entrée par variété.
La raison est simple, l'entrée du volume total se fait en une seule fois.
 
Par contre je peux avoir plusieurs sorties au fur et à mesure de la saison.
 
hinat        hivar         hidte        hiqte
  char        char         date         int
- entree | varieteX | 22/02/06 | 150
- sortie  | varieteX | 12/01/06 |  20
- sortie  | varieteX | 27/02/06 |  80
 
stvar            stqte
char             int
varieteX   |  50
 
 
Je vais tâcher d'être plus clair.
Si j'exécute :

Code :
  1. SELECT
  2.       stvar,
  3.       entree.hiqte,
  4.       sortie.hiqte,
  5.       FROM
  6.                 stock
  7.       LEFT OUTER JOIN historique AS entree ON ( entree.hivar = stvar AND entree.hinat='entree')
  8.       LEFT OUTER JOIN historique AS sortie ON ( sortie.hivar = stvar AND sortie.hinat='sortie')


J'obtiens :
VarieteX | 150 | 20
VarieteX | 150 | 80
 
Maintenant, j'execute :
 

SELECT
      stvar,
      sum(entree.hiqte),
      sum(sortie.hiqte),
      FROM
                stock
      LEFT OUTER JOIN historique AS entree ON ( entree.hivar = stvar AND entree.hinat='entree')
      LEFT OUTER JOIN historique AS sortie ON ( sortie.hivar = stvar AND sortie.hinat='sortie')
GROUP BY stvar


 
J'obtiens :
VarieteX | 300 | 100
 
Les entrées ont été comptées 2 fois parceque il y avait 2 sorties ...
 
Je vais chercher de mon côté mais si quelqu'un passe par là et connaît la solution, je le remercie par avance :jap:
 
 
EDIT
 
Bon jsuis un boulay, il suffit de faire

Code :
  1. SELECT
  2.       stvar,
  3.       entree.hiqte,
  4.       sum(sortie.hiqte),
  5.       FROM
  6.                 stock
  7.       LEFT OUTER JOIN historique AS entree ON ( entree.hivar = stvar AND entree.hinat='entree')
  8.       LEFT OUTER JOIN historique AS sortie ON ( sortie.hivar = stvar AND sortie.hinat='sortie')
  9. GROUP BY stvar


 
Par contre ca ne marche que si il y a une et une seule entrée par variété (mon cas actuellement).
Si quelqu'un sait comment faire la même requête pour admettons 2 entrées et 3 sorties sur la même variété sans se tapper un produit carthésien de neuneu, ca m'intéresse, dès fois que la structure évolue :)


Message édité par jeoff le 07-03-2006 à 11:08:13
Reply

Marsh Posté le 07-03-2006 à 11:20:30    

mouaip c'est normal, j'ai été un peu vite en besoigne :o
 
ça va être compliqué d'échapper à ce produit cartésien. Essaye en faisant tes 2 jointures séparement puis en faisant un union entre les deux.
 
Remarque ptêt que comme ça  

Code :
  1. sum(entree.hiqte) / coalesce(count(sortie.hiqte),1),
  2.      sum(sortie.hiqte) / coalesce(count(entree.hiqte),1),


Mais la faut tester je garantis rien du tout!

Reply

Marsh Posté le 07-03-2006 à 17:14:25    

Ok merci pour la piste, dès que jai un peu de temps, je posterais la requête qui marche :)

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed