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 : mettre à 0 des lignes qui n'ont pas de correspondances


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Inscrit en
    Novembre 2004
    Messages
    24
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Novembre 2004
    Messages : 24
    Points : 10
    Points
    10
    Par défaut Jointure : mettre à 0 des lignes qui n'ont pas de correspondances
    Bonjour,

    J'ai deux tables : l'une pour mes ventes et l'autre pour mes achats. Les deux tables ont la même structure : montant | mois | année

    J'aimerais créer une requête qui affiche par mois et par année les montant des achats et des ventes. Or, si j'ai une vente en décembre 2014, je n'aurai pas forcément d'achat à cette même période. Ce type de cas est donc ignoré (non affiché) lorsque l'on fait une jointure sur les champs mois et année des deux tables. Je voudrais que ma requête indique pour décembre 2014 le montant de la vente, et qu'elle affiche 0 pour le montant de l'achat, plutôt que de ne rien afficher.

    Possible ou non?

    Ma requête de base histoire de visualiser :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT table_achats.montant, table_vente.montant, table_achats.mois, table_achats.année
    FROM table_achats INNER JOIN table_vente 
    ON table_achats.mois = table_vente.mois AND table_achats.année = table_vente.année

    Mon plan B consiste à regrouper ces deux tables en une, mais pour éviter une étape supplémentaire, j'aimerais savoir si c'est possible via une requête.

    Merci

  2. #2
    Membre averti
    Homme Profil pro
    Consultant PLM
    Inscrit en
    Août 2007
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Consultant PLM

    Informations forums :
    Inscription : Août 2007
    Messages : 203
    Points : 304
    Points
    304
    Par défaut
    Regarde du côté du LEFT JOIN (ou LEFT INNER JOIN) plutôt que INNER JOIN.
    Par contre, j'imagine qu'il faudrait que tu gères également tous les cas possibles ? (exemple : sur un mois, aucune vente et aucun achat)

  3. #3
    Membre à l'essai
    Inscrit en
    Novembre 2004
    Messages
    24
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Novembre 2004
    Messages : 24
    Points : 10
    Points
    10
    Par défaut
    Oui effectivement je dois gérer tous les cas, donc un left ou right join ne suffira pas je pense.


    Dans le cas de 0 vente et 0 achat c'est encore autre chose, pas nécessaire de le gérer dans la requête je pense. Mais je dois gérer deux cas : 0 vente et 1 achat ou 1 vente et 0 achat.

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 043
    Points : 40 957
    Points
    40 957
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    Avec Firebird j'aurais fait ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT COALESCE(a.ANNEE,B.ANNEE) AS ANNEE, COALESCE(a.MOIS,b.MOIS) AS MOIS, COALESCE(a.MONTANT,0) AS ACHATS,COALESCE(b.MONTANT,0) AS VENTES
    FROM ACHATS a FULL JOIN VENTES B
    ON a.ANNEE=b.ANNEE AND a.MOIS=B.MOIS
    ORDER BY 1,2
    reste que le cas
    sur un mois, aucune vente et aucun achat
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  5. #5
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : bourreau
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2010
    Messages : 10 136
    Points : 38 912
    Points
    38 912
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par VTwin Voir le message
    Oui effectivement je dois gérer tous les cas, donc un left ou right join ne suffira pas je pense.


    Dans le cas de 0 vente et 0 achat c'est encore autre chose, pas nécessaire de le gérer dans la requête je pense. Mais je dois gérer deux cas : 0 vente et 1 achat ou 1 vente et 0 achat.
    En ce cas la solution est une jointure "FULL OUTER JOIN"

  6. #6
    Membre à l'essai
    Inscrit en
    Novembre 2004
    Messages
    24
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Novembre 2004
    Messages : 24
    Points : 10
    Points
    10
    Par défaut
    Merci pour vos réponses !

    J'ai oublié de préciser que pour le coup je bosse sous Access, et je me rends compte que les fonctions FULL OUTER JOIN et COALESCE n'existent pas. Bon au moins vos remarques me serviront sous MySQL

    J'ai en revanche trouvé une solution de remplacement à FULL OUTER JOIN qui semble fonctionner sous Access, à coup de LEFT OUTER JOIN, requête UNION, et fonction nz pour afficher 0 sur les lignes concernées : voir le topic

  7. #7
    ced
    ced est déconnecté
    Rédacteur/Modérateur

    Avatar de ced
    Homme Profil pro
    Gestion de bases de données techniques
    Inscrit en
    Avril 2002
    Messages
    6 016
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : Gestion de bases de données techniques
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 016
    Points : 23 705
    Points
    23 705
    Par défaut
    Citation Envoyé par VTwin Voir le message
    J'ai oublié de préciser que pour le coup je bosse sous Access, et je me rends compte que les fonctions FULL OUTER JOIN et COALESCE n'existent pas. Bon au moins vos remarques me serviront sous MySQL
    Dommage, MySQL n'implémente pas non plus le FULL OUTER JOIN.
    Là aussi, il existe un moyen de le simuler : http://mysql.developpez.com/telechar...ULL-OUTER-JOIN
    Rédacteur / Modérateur SGBD et R
    Mes tutoriels et la FAQ MySQL

    ----------------------------------------------------
    Pensez aux balises code et au tag
    Une réponse vous a plu ? N'hésitez pas à y mettre un
    Je ne réponds pas aux questions techniques par message privé, les forums sont là pour ça

  8. #8
    Membre à l'essai
    Inscrit en
    Novembre 2004
    Messages
    24
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Novembre 2004
    Messages : 24
    Points : 10
    Points
    10
    Par défaut
    Merci Ced pour le complément

  9. #9
    Modérateur
    Avatar de Waldar
    Homme Profil pro
    Customer Success Manager @Vertica
    Inscrit en
    Septembre 2008
    Messages
    8 452
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Customer Success Manager @Vertica
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2008
    Messages : 8 452
    Points : 17 820
    Points
    17 820
    Par défaut
    J'aurai fait comme ceci, à voir si Access accepte l'UNION et la vue :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      select annee, mois
           , sum(vente) as vente
           , sum(achat) as achat
        from (select annee, mois, montant as vente, 0 as achat
                from table_vente
               union all
              select annee, mois, 0 as vente, montant as achat
                from table_achats) as sr
    group by annee, mois
    order by annee, mois;

  10. #10
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 043
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 043
    Points : 40 957
    Points
    40 957
    Billets dans le blog
    62
    Par défaut
    +1 @Waldar et c'est même plus rapide
    je m'étais focalisé sur le titre : Jointure
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  11. #11
    Membre à l'essai
    Inscrit en
    Novembre 2004
    Messages
    24
    Détails du profil
    Informations personnelles :
    Âge : 44

    Informations forums :
    Inscription : Novembre 2004
    Messages : 24
    Points : 10
    Points
    10
    Par défaut
    Effectivement, je n'avais pas pensé à cette histoire d'UNION. Waldar, ça fonctionne parfaitement et ça semble bien plus propre que ma solution précédente, merci

  12. #12
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Etant donné qu'il y a le cas du mois sans vente et sans achat, je serais pas parti sur une FULL OUTER JOIN (ni le SUM de UNION, qui est une bonne alternative quand on n'a pas le choix).

    Je serais tout simplement parti d'un bête calendrier (tous les mois de toutes les années).
    avec deux LEFT OUTER JOIN vers VENTE et ACHAT.

    Simple et performant.

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    select c.annee, c.mois, coalesce(v.total) ventes, coalesce(a.total) achats
    from calendrier c
    left outer join ventes v on v.annee = c.annee and v.mois = c.mois
    left outer join achats a on a.annee = c.annee and a.mois = c.mois
    On ne jouit bien que de ce qu’on partage.

  13. #13
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    avec deux LEFT OUTER JOIN vers VENTE et ACHAT.
    En faisant ainsi, vous allez comptabiliser chaque vente autant de fois qu'il y aura eu d'achat dans le mois, et réciproquement...

    Il faudrait à la rigueur faire des agrégats par mois/année dans des sous requêtes

  14. #14
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 154
    Points : 7 403
    Points
    7 403
    Billets dans le blog
    1
    Par défaut
    Si je comprends bien, les cumuls sont déjà faits.

    Sinon, au pire, comme tu dis, il suffit de passer par une sous-requête et faire les agrégats en deux fois.
    On ne jouit bien que de ce qu’on partage.

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

Discussions similaires

  1. Suppression des lignes qui n'ont pas la plus grande valeur
    Par Oberown dans le forum Développement
    Réponses: 5
    Dernier message: 21/12/2012, 16h40
  2. Afficher des lignes qui n'ont pas de résultat
    Par Nessie37 dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 25/10/2007, 16h11
  3. UNION ? des lignes qui ne sont pas prises...
    Par fred23195 dans le forum Langage SQL
    Réponses: 3
    Dernier message: 01/12/2005, 14h50
  4. la liste des clients qui n'ont pas acheter aucun article ...
    Par TéBeSsI dans le forum Langage SQL
    Réponses: 6
    Dernier message: 13/02/2004, 14h57

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