IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage SQL Discussion :

Problème de join ou group by ou ?


Sujet :

Langage SQL

  1. #1
    Nouveau membre du Club
    Inscrit en
    Mars 2009
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 69
    Points : 34
    Points
    34
    Par défaut Problème de join ou group by ou ?
    Bonjour,

    J'ai besoin de votre aide pour résoudre mon problème.

    J'ai une table article et une table libellé complémentaire dans laquelle on trouve plusieurs libellés pour le même article sur plusieurs lignes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    ARTICLE :
    NOM LIBELLE
    001  VIS
    002  BOULON
    
    LIBELLECOM :
    NOM POS LIBELLECO
    001  01   CHC
    001  02   6x4
    001  03   INOX
    002  01   M4
    002  02  ACIER
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    RESULTAT SOUHAITE :
    001 VIS CHC 6X4 INOX
    003 BOULON M4 ACIER
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    RESULTAT OBTENU :
    001 VIS CHC
    001 VIS       6X4
    001 VIS             INOX
    002 BOULON M4
    002 BOULON      ACIER
    REQUETE :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT A.NOM, A.LIBELLE,
           CASE WHEN B.POS = '01' THEN B.LIBELLECO ELSE '' END,
           CASE WHEN B.POS = '02' THEN B.LIBELLECO ELSE '' END,
           CASE WHEN B.POS = '03' THEN B.LIBELLECO ELSE '' END
      FROM ARTICLE A,
           LIBELLECOM B
     WHERE A.NOM = B.NOM

    J'ai essayé avec un group by sur A.NOM, A.LIBELLE, B.POS, B.LIBELLECO mais cela ne marche pas comme je voudrais.

    Merci d'avance si vous pouvez m'aider à résoudre mon problème.

    Je précise que je suis sous iSeries AS400 ou MSQuery AS400.

    Cordialement

  2. #2
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Faites une recherche sur le mot PIVOT dans ce forum, vous devriez trouver votre solution.

  3. #3
    Nouveau membre du Club
    Inscrit en
    Mars 2009
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 69
    Points : 34
    Points
    34
    Par défaut
    J'ai cherché dans ce sens mais après plusieurs essais, j'en suis toujours au meme point.

  4. #4
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    En faisant une recherche sur PIVOT, je suis tombé sur une page complète avec une solution à votre problème dans chaque sujet.

  5. #5
    Nouveau membre du Club
    Inscrit en
    Mars 2009
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 69
    Points : 34
    Points
    34
    Par défaut
    PARFAIT, J'ai trouvé la bonne solution.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT A.NOM, A.LIBELLE,
               MAX(CASE WHEN B.POS = '01' THEN B.LIBELLECO END),
               MAX(CASE WHEN B.POS = '02' THEN B.LIBELLECO END),
               MAX(CASE WHEN B.POS = '03' THEN B.LIBELLECO END)
     
    FROM ARTICLE A, LIBELLECOM B
    JOIN BY A.NOM = B.NOM
    GROUP BY A.NOM, A.LIBELLE
    Merci à toi Waldar car c'est une de tes solutions.

    Cdlt

    Vincent

  6. #6
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Bravo !

  7. #7
    Nouveau membre du Club
    Inscrit en
    Mars 2009
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 69
    Points : 34
    Points
    34
    Par défaut
    En fait, j'ai un autre probleme lié a ce que je viens de faire.

    J'ai ajouté une table contenant des quantités et le résultat n'est pas cohérent.

    Admettons qu'on prenne un article qui possède 3 libéllés, il va me multiplier ma quantité par 3.
    Si l'article à 2 libéllés, il multiplira par 2.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT A.NOM, A.LIBELLE,C.QUANTITE
               MAX(CASE WHEN B.POS = '01' THEN B.LIBELLECO END),
               MAX(CASE WHEN B.POS = '02' THEN B.LIBELLECO END),
               MAX(CASE WHEN B.POS = '03' THEN B.LIBELLECO END),
               SUM(STOCKDISPO) 
     
    FROM ARTICLE A, LIBELLECOM B
    JOIN BY A.NOM = B.NOM, B.NOM = C.NOM
    GROUP BY A.NOM, A.LIBELLE
    Admettons que j'ajoute B.POS et B.LIBELLECO dans le group by, on verai 3 fois la même ligne mais avec les bonnes quantité.

    J'ai essayé de mettre de Distinct ou autres pour palier à cet effet indésirable mais sans succès.

    Une idée ?

  8. #8
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    bonjour,

    sans connaitre les relations entre votre nouvelle table et les anciennes, on peut difficilement donné un avis sur la chose !

  9. #9
    Nouveau membre du Club
    Inscrit en
    Mars 2009
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 69
    Points : 34
    Points
    34
    Par défaut
    Oui je comprends.
    Disons que seul NOM est en commun entre les 3 tables.

    Et de plus, cette multiplication des bonnes quantité dépand vraiment du nombre de libellé de l'article.

  10. #10
    Nouveau membre du Club
    Inscrit en
    Mars 2009
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 69
    Points : 34
    Points
    34
    Par défaut
    En fait, j'ai trouvé ça comme solution :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT A.NOM, A.LIBELLE,C.QUANTITE
               MAX(CASE WHEN B.POS = '01' THEN B.LIBELLECO END),
               MAX(CASE WHEN B.POS = '02' THEN B.LIBELLECO END),
               MAX(CASE WHEN B.POS = '03' THEN B.LIBELLECO END),
               SUM(CASE WHEN B.POS = '01' THEN STOCKDISPO) 
     
    FROM ARTICLE A, LIBELLECOM B
    JOIN BY A.NOM = B.NOM, B.NOM = C.NOM
    GROUP BY A.NOM, A.LIBELLE
    C'est fonctionnel, mais pas très académique, car je ne sais pas ce qu'il se passera si B.POS est vide.
    Si vous avez une solution plus adaptée, je suis preneur.

    Merci d'avance.

    Vincent

  11. #11
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Il vaudrait mieux effectuer la jointure après :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
      SELECT SR.NOM, SR.LIBELLE,
             SR.LIBELLECO_01,
             SR.LIBELLECO_02,
             SR.LIBELLECO_03,
             SUM(C.STOCKDISPO)
        FROM ( SELECT A.NOM, A.LIBELLE,
                      MAX(CASE WHEN B.POS = '01' THEN B.LIBELLECO END) AS LIBELLECO_01,
                      MAX(CASE WHEN B.POS = '02' THEN B.LIBELLECO END) AS LIBELLECO_02,
                      MAX(CASE WHEN B.POS = '03' THEN B.LIBELLECO END) AS LIBELLECO_03
                 FROM ARTICLE A
                      INNER JOIN LIBELLECOM B
                        ON B.NOM = A.NOM
                WHERE B.POS IN ('01', '02', '03') -- facultatif si ce sont toutes vos valeurs
             GROUP BY A.NOM, A.LIBELLE
             ) SR
             INNER JOIN TROISIEMETABLE C
               ON C.NOM = SR.NOM
    GROUP BY SR.NOM, SR.LIBELLE,
             SR.LIBELLECO_01,
             SR.LIBELLECO_02,
             SR.LIBELLECO_03
    J'en ai profité pour normaliser vos jointures.

  12. #12
    Nouveau membre du Club
    Inscrit en
    Mars 2009
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 69
    Points : 34
    Points
    34
    Par défaut
    Merci Waldar, je vais regarder de plus près.

  13. #13
    Nouveau membre du Club
    Inscrit en
    Mars 2009
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 69
    Points : 34
    Points
    34
    Par défaut
    Bon, après de nombreux essais, je n'ai pas réussi à adapter ta requète waldar.

    Je suis en sql DB2 (Iséries ODBC AS400) et cela n'est peut être pas faisable sous cette forme.

  14. #14
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Sr. Specialist Solutions Architect @Databricks
    Inscrit en
    Septembre 2008
    Messages
    8 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Sr. Specialist Solutions Architect @Databricks
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 453
    Points : 18 388
    Points
    18 388
    Par défaut
    Ce n'est pourtant qu'une simple sous requête !

  15. #15
    Nouveau membre du Club
    Inscrit en
    Mars 2009
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 69
    Points : 34
    Points
    34
    Par défaut
    Il me met différentes erreurs dont FROM INTO...
    ou
    SQL0199 - Le mot clé FROM est mal placé. Eléments possibles : FOR WITH FETCH ORDER UNION EXCEPT OPTIMIZE.

  16. #16
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Mai 2002
    Messages
    3 173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 173
    Points : 5 345
    Points
    5 345
    Par défaut
    Mais tu essais exactement la requête qu'il te donne ou une adaptation perso ?

    sous Iseries sa requête doit passer, il n'y a rien de particulier.

    edit : Dans le doute, essai en sortant la sous requête dans un with

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    WITH TMP AS (
    SELECT A.NOM, A.LIBELLE,
    MAX(CASE WHEN B.POS = '01' THEN B.LIBELLECO END) AS LIBELLECO_01,
    MAX(CASE WHEN B.POS = '02' THEN B.LIBELLECO END) AS LIBELLECO_02,
    MAX(CASE WHEN B.POS = '03' THEN B.LIBELLECO END) AS LIBELLECO_03
    FROM ARTICLE A
    INNER JOIN LIBELLECOM B ON B.NOM = A.NOM
    WHERE B.POS IN ('01', '02', '03') -- facultatif si ce sont toutes vos valeurs
    GROUP BY A.NOM, A.LIBELLE)
     
     
    SELECT SR.NOM, SR.LIBELLE,
             SR.LIBELLECO_01,
             SR.LIBELLECO_02,
             SR.LIBELLECO_03,
             SUM(C.STOCKDISPO)
        FROM TMP SR
        INNER JOIN TROISIEMETABLE C ON C.NOM = SR.NOM
        GROUP BY SR.NOM, SR.LIBELLE,
             SR.LIBELLECO_01,
             SR.LIBELLECO_02,
             SR.LIBELLECO_03

  17. #17
    Nouveau membre du Club
    Inscrit en
    Mars 2009
    Messages
    69
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 69
    Points : 34
    Points
    34
    Par défaut
    en fait elle fonctionne.

    Je viens de découvrir une option qui me propose :

    SELECT à traiter en format transfert de données
    SELECT à traiter en format natif SQL

    J'ai toujours été paramétré en format transfert de données, car il me permet de voir a quoi correspondent les codes des mes tables.
    En natif sql ça passe parfaitement.

    Donc Merci pour tout.

    (je vais essayer le with pour voir !!)

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème SELECT, CASE et Group by
    Par Royd938 dans le forum MS SQL Server
    Réponses: 9
    Dernier message: 03/10/2014, 07h41
  2. Problème count Join group by
    Par casa_sniper dans le forum PL/SQL
    Réponses: 5
    Dernier message: 08/12/2011, 12h21
  3. Problème left outer join et group by
    Par maya13400 dans le forum Langage SQL
    Réponses: 4
    Dernier message: 05/09/2010, 20h40
  4. Problème INNER JOIN GROUP BY
    Par benjisan dans le forum Requêtes et SQL.
    Réponses: 5
    Dernier message: 16/05/2007, 16h18
  5. requete avec left join et group by
    Par slc dans le forum Requêtes
    Réponses: 2
    Dernier message: 14/09/2004, 18h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo