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 :

Jointure avec une clause where


Sujet :

Langage SQL

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 146
    Points
    146
    Par défaut Jointure avec une clause where
    Bonjour,

    J'ai besoin d'aide sur un requete qui joint un produit a la quantité commandé de ce meme produit. La requete est la suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    SELECT Product.Qty,SUM(POProduct.Qty) 
    FROM (Product LEFT JOIN POProduct ON Product.IDProduct = POProduct.IDProduct) LEFT JOIN PurchaseOrder ON POProduct.IDPO = PurchaseOrder.IDPO
    WHERE PurchaseOrder.ToDate = ""
    GROUP BY Product.Qty
    Breve explication : cette requête joint la quantité de produit avec la quantité commandé. La table PurchaseOrder étant la description des commandes et la table POProduct étant les items commandés (Tout les produits commandés). Le champs ToDate de la Table PurchaseOrder me permet de savoir si la commande de produit est arrivé ( <> "") ou non (= "").

    En executant cette requête j'obtient les quantités des produits dont il y a au moin une commande qui n'est pas encore arrivé et ce ne pas ce que je souhaite.

    exemple de résultat :

    Produit x : Qty : 10 QtyCommandé : 10
    et les autres produits ne s'affiche pas a cause de la clause WHERE.

    Je souhaite avoir TOUT LES PRODUITS comme résultat donc en enlevant la clause WHERE cela fonctionne mais j'ai le total des commandes qui sont arrivé et qui ne le sont pas. donc ma clause WHERE est obligatoire.

    Comment je pourrais avoir un résultat du genre :

    produit x : Qty : 10 QtyCommandé : 10
    produit y : Qty : 8 QtyCommandé : 0
    Produit n.. : Qty : n.. QtyCommandé : n..

    Cette requete étant sous Access 2000.

    Merci et j'espère que mon explication est suffisamment claire.

  2. #2
    Membre averti Avatar de AL1986
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    434
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 434
    Points : 441
    Points
    441
    Par défaut
    Salut,
    Citation Envoyé par pepi22
    En executant cette requête j'obtient les quantités des produits dont il y a au moin une commande qui n'est pas encore arrivé et ce ne pas ce que je souhaite.
    Je souhaite avoir TOUT LES PRODUITS comme résultat donc en enlevant la clause WHERE cela fonctionne mais j'ai le total des commandes qui sont arrivé et qui ne le sont pas
    Ta requête serait donc : Avoir pour chaque produit, sa quantité et le total des quantités commandées concernant les commandes non encore arrivées ; et dans le cas où toutes les commandes concernant un produit seraient arrivées avoir 0.
    Me trompe-je?
    Etre ou ne pas être, telle est la question sinusoïdale de l'anachorète hypocondriaque et vice et versa .
    Bonsai monsieur, bonsai madame, vous avez gagnez un milliard de degrés au soleil .
    There is no cure for stupidity (ou pas ).

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 146
    Points
    146
    Par défaut
    Vous avez parfaitement compris ALI986.

    Je sais pas trop comment arranger ma requete pour arriver à ce résultat...

  4. #4
    Membre averti Avatar de AL1986
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    434
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 434
    Points : 441
    Points
    441
    Par défaut
    D'abord, je pense qu'il faut aussi selectionner l'IDProduct et faire un group by en l'utilisant (ainsi que Qty) car il se pourrait que tu ais deux IDProduct différents mais dont les Qty sont pareilles et ton group by ne fera pas la différence entre les produits.
    Pour ce qui est du 0 (qui semble être la source de tous nos tracas), je ne sais pas si l'opérateur sum renvoie un 0 s'il ne trouve rien à sommer.
    Le where que tu introduis effectue la selection de todate="" avant de constituer les groupes et donc c'est normal qu'il ne te selectionne que les produits ayant au moins une commande en retard.
    Tu peux essayer cette requête et me dire si le resultat change :
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT P.IDProduct, P.Qty, SUM(PO.Qty) 
    FROM Product P, POProduct PO, PurchaseOrder PuO 
    WHERE P.IDProduct = PO.IDProduct
    AND PO.IDPO = PuO.IDPO
    GROUP BY P.IDProduct, P.Qty
    HAVING PuO.ToDate = "";
    Cette requête devrait t'afficher les produits ayant au moins une commande en retard et si sum renvoie 0 qd il ne trouve rien à calculer, tu auras peut être les autres produits.
    Etre ou ne pas être, telle est la question sinusoïdale de l'anachorète hypocondriaque et vice et versa .
    Bonsai monsieur, bonsai madame, vous avez gagnez un milliard de degrés au soleil .
    There is no cure for stupidity (ou pas ).

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 146
    Points
    146
    Par défaut
    J'ai quand même essayer la requête que vous m'avez écrite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT P.IDProduct, P.Qty, SUM(PO.Qty) 
    FROM Product P, POProduct PO, PurchaseOrder PuO 
    WHERE P.IDProduct = PO.IDProduct
    AND PO.IDPO = PuO.IDPO
    GROUP BY P.IDProduct, P.Qty
    HAVING PuO.ToDate = "";
    Il faut absolument une jointure LEFT JOIN car la jointure standard tronque déja les résultats (pas tout les produits seront afficher).
    J'ai essayer des variation avec le HAVING plutot que le WHERE mais sans resultat.

    Une solution qui selon moi serait efficace, serait d'ajouter une clause au dernier left join du genre:¨

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    LEFT JOIN PurchaseOrder ON POProduct.IDPO = PurchaseOrder.IDPO AND
    PurchaseOrder.ToDate = ""
    Mais cette syntaxe n'a pas l'air d'être reconnu sous access

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 146
    Points
    146
    Par défaut
    Pour répondre au problème de la commande SUM:

    S'il n'y a pas d'enregistrement SUM retourne la valeur NULL.

    Exemple de résultat

    Produit x : Qty : 10 QtyCommandé : 8
    Produit Y : Qty : 6 QtyCommandé :

    N.B : Ce resultat s'affiche en supprimant la clause WHERE

  7. #7
    Membre averti Avatar de AL1986
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    434
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 434
    Points : 441
    Points
    441
    Par défaut
    Et s'il n y a aucune commande concernant un certain produit (produit n'étant pas présent dans les tables POProduct et PurchaseOrder, tu voudrais aussi avoir 0 ?
    Etre ou ne pas être, telle est la question sinusoïdale de l'anachorète hypocondriaque et vice et versa .
    Bonsai monsieur, bonsai madame, vous avez gagnez un milliard de degrés au soleil .
    There is no cure for stupidity (ou pas ).

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 146
    Points
    146
    Par défaut
    Non ce n'est pas nécessaire je peux facilement le gérer en delphi.

    Une autre solution intéressante serait un union. En très bref :

    SELECT Product.Qty, (_quantité_commandé)
    UNION SELECT Product.Qty, 0

    Le seul problème est que je me retrouve avec des doublons car le deuxième champs est différent de celui de la première requête.

  9. #9
    Membre averti Avatar de AL1986
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    434
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 434
    Points : 441
    Points
    441
    Par défaut
    Tu utilises donc ta première requête pour sélectionner les produits ayant au moins une commande non encore arrivée. La deuxième doit servir à sélectionner les produits qui restent, en l'occurrence, ceux ayant au plus zéro commandes non encore arrivées (dont toutes les commandes sont arrivées) en forçant le deuxième champs à 0.
    Tu pourrais mettre dans ta deuxième requête une requête imbriquée:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    ....where P.IDProduct not in (select P1.IDProduct from....);
    c'est lourd comme écrirure et je ne sais pas si ça peux effectivement supprimer les doublons.
    Essaie et tiens mois au courant.
    Etre ou ne pas être, telle est la question sinusoïdale de l'anachorète hypocondriaque et vice et versa .
    Bonsai monsieur, bonsai madame, vous avez gagnez un milliard de degrés au soleil .
    There is no cure for stupidity (ou pas ).

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 146
    Points
    146
    Par défaut
    En effet cela fonctionne. J'ai peur du temps d'execution de la requête sur un grand nombre de données. (et je suis contre l'utilisation de l'union dans une requete mais pour l'instant je n'ai pas de meilleur solution)

    Mais bon, il doit surement exister une façon d'afficher tout les resultats sans l'aide de l'union et d'une façon plus propre. (Sinon le sql est très limité et j'en suis dégouté)

    Merci beaucoup de votre aide, si vous avez une meilleure solution que l'union,
    s'il vous plait veuillez m'en fait part car mon idée était très brouillon .

  11. #11
    Membre averti Avatar de AL1986
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    434
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 434
    Points : 441
    Points
    441
    Par défaut
    Je suis complètement d'accord avec toi, la requête est très lourde et il doit sûrement y avoir plus optimal, mais pour le moment je ne vois pas vraiment comment faire autrement. Si j'ai une révélation, je ne manquerai pas de t'en aviser.
    Etre ou ne pas être, telle est la question sinusoïdale de l'anachorète hypocondriaque et vice et versa .
    Bonsai monsieur, bonsai madame, vous avez gagnez un milliard de degrés au soleil .
    There is no cure for stupidity (ou pas ).

  12. #12
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    Salut,

    je vais essayé de t'aider :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT Product.Qty, ISNULL(SUM (POProduct.Qty), 0) 
    FROM Product 
    LEFT OUTER JOIN POProduct 
    ON Product.IDProduct = POProduct.IDProduct
    LEFT OUTER JOIN PurchaseOrder 
    ON POProduct.IDPO = PurchaseOrder.IDPO
    AND PurchaseOrder.ToDate = ""
    GROUP BY Product.Qty
    Cela devrait fonctionner, à voir si ca donne le bon résultat car ton explication est un poil fouillis pour moi
    Mindiell
    "Souvent, femme barrit" - Elephant man

  13. #13
    Membre averti Avatar de AL1986
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    434
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 434
    Points : 441
    Points
    441
    Par défaut
    le
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    AND PurchaseOrder.ToDate = ""
    ne restreint il pas la selection ? Puisque les produits dont toutes les commandes sont arrivées ne sont pas selectionnés.
    Etre ou ne pas être, telle est la question sinusoïdale de l'anachorète hypocondriaque et vice et versa .
    Bonsai monsieur, bonsai madame, vous avez gagnez un milliard de degrés au soleil .
    There is no cure for stupidity (ou pas ).

  14. #14
    Membre confirmé
    Avatar de Mindiell
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    735
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 735
    Points : 546
    Points
    546
    Par défaut
    le critère est contenu dans le left outer join, il fait donc partie uniquement de la sélection de la table PurchaseOrder. Ensuite, celle-ci est jointe de manière ouverte à POProduct.

    Donc, non, cela limite le résultat de PurchaseOrder, mais pas de la requête totale.
    Mindiell
    "Souvent, femme barrit" - Elephant man

  15. #15
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 146
    Points
    146
    Par défaut
    Désolé pour mon absence,

    Je n'ai rien trouvé d'autre qui pourrait m'aider et la requête malgré sa structure s'execute quand même rapidement donc je vais garder cette solution. Merci a tous.

  16. #16
    Membre habitué
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Canada

    Informations forums :
    Inscription : Juillet 2007
    Messages : 203
    Points : 146
    Points
    146
    Par défaut
    Mindiell : La requête que vous avez écrite est déja écrite plus haut et sa syntaxe n'est pas reconnu par access. (étrangement OR dans un LEFT JOIN ne provoque pas d'erreur mais AND oui).

    Et oui la clause WHERE limite le résultat de la requete total.

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

Discussions similaires

  1. [Toutes versions] INSERT INTO avec une Clause Where
    Par casavba dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 02/02/2010, 21h16
  2. Mettre à jour un champ Boolean avec une clause "WHERE"
    Par niano dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 02/10/2007, 11h29
  3. DELETE avec une clause where
    Par liberty74 dans le forum Requêtes
    Réponses: 3
    Dernier message: 27/08/2007, 11h56
  4. Insert avec une clause where !?
    Par Thomad dans le forum MS SQL Server
    Réponses: 8
    Dernier message: 04/08/2006, 09h55
  5. [super requete] Dumper un model avec une clause where
    Par elievar dans le forum Langage SQL
    Réponses: 3
    Dernier message: 16/03/2005, 17h05

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