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

Requêtes MySQL Discussion :

Récupérer les commandes et les factures si ces dernières existent


Sujet :

Requêtes MySQL

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 685
    Points : 132
    Points
    132
    Par défaut Récupérer les commandes et les factures si ces dernières existent
    Bonjour,


    J'ai une table de commandes.

    Et une table de factures.

    Une requête permet au client de voir toutes les commandes avec pour chaque commande la facture associée.

    Mais certaines commandes n'ont pas de factures, soit car elles ne sont pas validées, soit car elles sont à l'état de demande de devis.

    Je cherche une requête pour sortir toutes les commandes y compris celles qui n'ont pas de facture.

    Cette requête ne sort que les commandes qui ont des factures :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $requete = "SELECT parametres_commande, etc, etc, etc , numero_facture
     
    FROM table_commandes, table_factures
     
    WHERE table_commandes.numero_client='". intval ($numero_client) . "' AND table_commandes,.numero_commande=table_factures.numero_commande";
    Comment l'améliorer pour l'objectif voulu ?

    Je précise qu'il existe au plus une facture par commande.

    La stratégie de ne chercher que les commandes puis pour chaque commande d'aller chercher la facture prend trop de temps quand le client a de nombreuses commandes.

    J'espère que c'est clair.

    Merci de votre aide.

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 233
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 233
    Points : 12 847
    Points
    12 847
    Par défaut
    Bonjour,
    Il faut partir de la table des commandes, et faire une jointure externe sur la table des factures.

    Tatayo.

  3. #3
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 188
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 188
    Points : 8 390
    Points
    8 390
    Billets dans le blog
    17
    Par défaut
    Comme le dit tatayo, il faut passer par une jointure externe.

    Dans le principe :

    Code PHP : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    $sql = <<<SQL
        SELECT ALL c.numbero_client, f.numero_commande
        FROM commande AS c
        LEFT OUTER JOIN facture AS f ON c.numero_commande = f.numero_commande
        WHERE c.numerco_client = {$pdo->quote($numero_client)}
        SQL;

    numero_commande sera NULL si pas de facture rattachée à la commande.
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 685
    Points : 132
    Points
    132
    Par défaut
    Bonjour,

    Merci pour vos retours.

    Je teste le LEFT OUTER JOIN ce soir.

    Ma crainte concerne le temps de réponse avec un JOIN.

    Je vous tiens informés.

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 233
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable Données

    Informations forums :
    Inscription : Janvier 2009
    Messages : 5 233
    Points : 12 847
    Points
    12 847
    Par défaut
    Citation Envoyé par boteha Voir le message
    Bonjour,
    Ma crainte concerne le temps de réponse avec un JOIN.
    Tu penses vraiment que ces deux écritures vont donner des temps de réponses différents ?
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT parametres_commande, etc, etc, etc , numero_facture
    FROM table_commandes, table_factures
    WHERE table_commandes.numero_client='". intval ($numero_client) . "' AND table_commandes,.numero_commande=table_factures.numero_commande
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT parametres_commande, etc, etc, etc , numero_facture
    FROM table_commandes
    INNER JOIN table_factures
        ON table_commandes,.numero_commande=table_factures.numero_commande
    WHERE table_commandes.numero_client='". intval ($numero_client) . "'
    Il n'en est rien*. Les deux écritures sont "équivalentes", mais la seconde est bien plus lisible (séparation des critères de jointure des critères de filtre).

    Quoi qu'il en soit, si tu veux toutes les commandes et les éventuelles factures, tu n'as pas d'autres choix que de passer par une jointure externe.
    Un peu plus d'infos .

    Tatayo.

    *: en tout cas avec SqlServer, à vérifier quand même avec MySQL.

  6. #6
    Expert éminent
    Avatar de Séb.
    Profil pro
    Inscrit en
    Mars 2005
    Messages
    5 188
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2005
    Messages : 5 188
    Points : 8 390
    Points
    8 390
    Billets dans le blog
    17
    Par défaut
    Ma crainte concerne le temps de réponse avec un JOIN.
    Tu avais déjà un JOIN avec ta ,

    SELECT ...
    FROM table_commandes, table_factures
    WHERE table_commandes.numero_commande = table_factures.numero_commande AND table_commandes.numero_client = :num_client
    Est strictement identique à :

    SELECT ...
    FROM table_commandes
    CROSS JOIN table_factures
    WHERE table_commandes.numero_commande = table_factures.numero_commande AND table_commandes.numero_client = :num_client
    Elle-même strictement identique à :

    SELECT ...
    FROM table_commandes
    INNER JOIN table_factures ON table_commandes.numero_commande = table_factures.numero_commande
    WHERE table_commandes.numero_client = :num_client
    Le OUTER JOIN ne devrait pas changer grand chose.
    Un problème exposé clairement est déjà à moitié résolu
    Keep It Smart and Simple

  7. #7
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 275
    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 275
    Points : 39 484
    Points
    39 484
    Billets dans le blog
    9
    Par défaut
    @boteha : ça fait 30 ans que les jointures ne s'écrivent plus dans la restriction WHERE, mais avec l'opérateur JOIN.
    et c'est tant mieux, car restriction et jointure sont deux opérations différentes, la restriction s'opère après la jointure, sur le jeu de données résultant de celle-ci

    @Séb. : compte tenu de ce qui précède, faire un produit cartésien avec CROSS JOIN puis appliquer une restriction avec WHERE n'est pas la même chose que de faire une jointure interne ou externe avec JOIN.
    Certes, l'optimiseur sait souvent optimiser une telle opération en remplaçant dans ce cas le produit cartésien par une jointure pour la rendre indolore, mais ce n'est pas systématique et c'est donc une mauvaise pratique.
    Donc au mieux faire la jointure dans le WHERE ou dans le JOIN sont d'égale performance, parce que l'optimiseur veille au grain, au pire, la coder dans le WHERE dégrade les performances.
    Par ailleurs, une jointure externe (OUTER JOIN) sera le plus souvent plus lente à exécuter qu'une jointure interne, puisque le nombre de lignes en résultat est plus important

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 685
    Points : 132
    Points
    132
    Par défaut
    Bonjour,

    Merci beaucoup de votre suivi.

    J'ai placé un LEFT OUTER JOIN comme conseillé par tatayo ou seb.

    Je dois dire que dans la vie réelle le temps de réponse est quasi-immédiat avec une grosse centaine de commandes / factures alors qu'un SELECT par commande bouffait plusieurs secondes.

    J'ai été traumatisé par un hébergeur qui me demandait d'éviter les JOIN comme la peste, cela il y a une dizaine d'années.

    Je potasse un peu CROSS JOIN et INNER JOIN avant de cocher Résolu.

  9. #9
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 275
    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 275
    Points : 39 484
    Points
    39 484
    Billets dans le blog
    9
    Par défaut

    Citation Envoyé par boteha Voir le message
    J'ai été traumatisé par un hébergeur qui me demandait d'éviter les JOIN comme la peste, cela il y a une dizaine d'années.
    Un hébergeur qui ne connait absolument rien à SQL !


    Citation Envoyé par boteha Voir le message
    Je potasse un peu CROSS JOIN et INNER JOIN avant de cocher Résolu.
    Attention : CROSS JOIN c'est le produit cartésien des tables en jeu, ça peut vite produire des volumes considérables. À n'utiliser qu'à bon escient (bien pratique pour créer des jeux d'essais par exemple).
    et il faut également étudier LEFT OUTER JOIN, RIGHT OUTER JOIN et dans une moindre mesure FULL OUTER JOIN

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 685
    Points : 132
    Points
    132
    Par défaut
    Bonjour,

    Citation Envoyé par escartefigue Voir le message
    :
    Attention : CROSS JOIN c'est le produit cartésien des tables en jeu, ça peut vite produire des volumes considérables. À n'utiliser qu'à bon escient (bien pratique pour créer des jeux d'essais par exemple).
    et il faut également étudier LEFT OUTER JOIN, RIGHT OUTER JOIN et dans une moindre mesure FULL OUTER JOIN
    C'est noté, merci.

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 685
    Points : 132
    Points
    132
    Par défaut
    Bonjour,

    Je pense avoir compris que ',' = CROSS JOIN = produit cartésien.

    INNER JOIN j'ai aussi compris.
    J'utilise INNER JOIN dans presque tous les cas où il y avait deux tables liées par une ','.
    Sauf erreur l'ordre des deux tables est sans importante ?

    FROM table_1 INNER JOIN table_2 ON table_1.ca_id=table_2.ca_id
    est équivalent à :
    FROM table_2 INNER JOIN table_1 ON table_1.ca_id=table_2.ca_id

    Enfin LEFT OUTER JOIN, j'ai aussi compris.

    Cela doit suffire à traiter toute mes jointures.

    Merci de votre aide, j'attends un peu avant de cocher Résolu.

  12. #12
    Modérateur
    Avatar de escartefigue
    Homme Profil pro
    bourreau
    Inscrit en
    Mars 2010
    Messages
    10 275
    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 275
    Points : 39 484
    Points
    39 484
    Billets dans le blog
    9
    Par défaut
    Citation Envoyé par boteha Voir le message
    CROSS JOIN = produit cartésien.
    Oui


    Citation Envoyé par boteha Voir le message
    FROM table_1 INNER JOIN table_2 ON table_1.ca_id=table_2.ca_id
    est équivalent à :
    FROM table_2 INNER JOIN table_1 ON table_1.ca_id=table_2.ca_id
    Oui : la jointure interne (INNER JOIN) est commutative


    Citation Envoyé par boteha Voir le message
    Enfin LEFT OUTER JOIN, j'ai aussi compris.
    Mais attention, les jointures externes droite (RIGHT OUTER JOIN) et gauche (FULL OUTER JOIN) ne sont pas commutatives :
    from T1 left join T2 on T2.COLx = T1.COLx n'est pas égale à from T2 left join T1 on T1.COLx = T2.COLx.
    La jointure externe FULL OUTER JOIN, elle, est commutative


    Citation Envoyé par boteha Voir le message
    Cela doit suffire à traiter toute mes jointures.
    Non, il existe aussi :
    • la jointure externe RIGHT OUTER JOIN
    • la jointure externe FULL OUTER JOIN
    • l'intra jointure CROSS APPLY
    • l'intra jointure OUTER APPLY
    • l'anti jointure, basée sur une jointure externe, dont on ne retient que les orphelins
    • la jointure naturelle NATURAL JOIN (rarement utilisée, car très dangereuse)
    • la jointure union UNION JOIN

  13. #13
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 685
    Points : 132
    Points
    132
    Par défaut
    Bonjour escartefigue,

    Encore merci de ton suivi.

    Je veux dire que les INNER JOIN et LEFT OUTER JOIN suffisent à traiter tous les cas auxquels je suis confrontés.

    Je vais éplucher la suite de la liste.

  14. #14
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    685
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 685
    Points : 132
    Points
    132
    Par défaut
    Bonjour,

    J'ai coché Résolu.

    Encore merci pour votre aide.

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 05/05/2010, 17h08
  2. [Détente] Les API étranges: ces classes au comportement curieux.
    Par grunt2000 dans le forum API standards et tierces
    Réponses: 2
    Dernier message: 14/11/2007, 14h31
  3. rajouter l'origine des produits sur les factures
    Par Bob2175 dans le forum Oracle
    Réponses: 1
    Dernier message: 21/11/2006, 19h03
  4. [Contexte][Alias]Quelles sont les definitions de ces termes?
    Par Melvine dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 07/12/2005, 18h09
  5. Réponses: 17
    Dernier message: 31/08/2005, 17h03

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