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 :

optimiser, toujours optimiser


Sujet :

Requêtes MySQL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    None
    Inscrit en
    Mars 2008
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : None

    Informations forums :
    Inscription : Mars 2008
    Messages : 58
    Par défaut optimiser, toujours optimiser
    Bonjour.

    Travaillant actuellement sur le développement de la partie statistique d'un back-office, je n'arrive pas à trouver la requête miracle qui m'évitera d'avoir à procéder par étapes.

    But recherché: savoir, parmi les clients qui ont commandés sur un mois donné, ceux qui en sont à leur première commande, ceux qui en sont à leur 2e, à leur 3e, à leur 4e ou à 5 et +.

    Actuellement, je procéde ainsi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT a.id_client, COUNT( DISTINCT b.id_commande ) AS nb_commandes
    FROM commande a
    INNER JOIN commande b ON ( a.id_client = b.id_client
    AND b.date_commande < "2008-04-01 00:00:00")
    WHERE a.date_commande
    BETWEEN "2008-03-01 00:00:00"
    AND "2008-03-31 23:59:59"
    GROUP BY a.id_client
    HAVING nb_commandes=1
    pour connaitre les clients ayant commandés en mars qui n'en sont qu'à leur première commande, puis je regarde le nombre de réponses retournées (j'ai bien essayé d'envelopper la requéte dans un SELECT COUNT() général, mais j'ai un message d'erreur et passe donc par l'instruction php mysql_num_rows).

    Comme je veux 5 nombres, je répéte l'opération 5 fois, en changeant chaque fois la condition de mon Y'aurait-il moyen d'optimiser tout ça pour obtenir le résultat souhaité en une seule et unique requéte?

    Merci d'avance.

    P.S.: le serveur est en MySQL 4.0.2, donc sous-requétes impossibles.

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France, Essonne (Île de France)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 130
    Par défaut
    Bonjour

    Il y a surtout beaucoup plus simple en 2 requêtes !

    L'une qui compte le nombre total de commande par client
    L'autre qui compte le nombre de commandes du mois par client

    Cette manie de la requête miracle qui fait tout et son contraire

  3. #3
    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 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loiret (Centre)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 063
    Par défaut
    Bonjour,

    Dans une jointure interne, le AND n'apporte rien de plus par rapport à la même condition dans la clause WHERE (c'est avec les jointures externes que ça change).
    En revanche, tu peux faire ce que tu souhaites avec une jointure sur une sous-requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    SELECT a.id_client, b.nb_commandes 
    FROM commande a
    INNER JOIN (
      SELECT id_client, COUNT(id_commande) as nb_commande
      FROM commande
      WHERE date_commande < '2008-04-01 00:00:00'
      GROUP BY id_client
    ) as b ON a.id_client = b.id_client
    WHERE a.date_commande BETWEEN '2008-03-01 00:00:00' AND '2008-03-31 23:59:59'
    ORDER BY b.nb_commandes
    C'est ce que propose comico, mais en une seule requête "miracle" .

    ced
    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

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    130
    Détails du profil
    Informations personnelles :
    Localisation : France, Essonne (Île de France)

    Informations forums :
    Inscription : Octobre 2007
    Messages : 130
    Par défaut
    Le Monsieur a dit "pas de sous requête" !

  5. #5
    Membre confirmé
    Profil pro
    None
    Inscrit en
    Mars 2008
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : None

    Informations forums :
    Inscription : Mars 2008
    Messages : 58
    Par défaut
    Ced, à moins qu'une subtilité m'échappe, ta requéte renvoie à peu près la même chose que celle que j'avais présentée (la différence tient surtout au fait que tu n'as pas précisé DISTINCT id_client dans ton SELECT, ce qui fait que si tu as eu plusieurs commandes sur le mois, tu obtiens plusieurs lignes avec le même couple (id_client, nb_commandes)).

    Ceci dit, je suis content que tu l'aies envoyée parce que c'est un type de formulation que je n'avais jamais vu. Ça me permet de voir d'autres techniques que celles que je rabâche à longueur de journée, et ça m'ouvre de nouveaux horizons. Je n'aurais jamais pensé à faire un INNER JOIN sur un SELECT. Du coup, je note, ça pourra me servir un jour (mais pas sur un serveur en 4.0.2)

    Et il semblerait que je me sois mal exprimé dans mon message initial. Qui a passé combien de commandes, ce n'est pas ce que je cherche. La requéte idéale que je voulais, c'est celle qui me renverrait 5 valeurs, soit le nb de client ayant commandé (une fois), (2 fois), (3 fois), (4 fois) et (5 fois et +) tout en ayant passé une commande dans le mois sélectionné.

    Je n'ai pas besoin de différencier mes clients en sortie, je veux juste savoir combien il sont à appartenir à chacun des 5 groupes sus-cités.

  6. #6
    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 063
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Loiret (Centre)

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

    Informations forums :
    Inscription : Avril 2002
    Messages : 6 063
    Par défaut
    Ah ben ça m'apprendra à ne pas lire les messages jusqu'au bout .
    Bon, alors en une seule requête sans sous-requêtes, là ça ne sera pas possible.
    En revanche, tu peux faire une table temporaire avec la sous-requête précédente, puis faire la même jointure... Au passage, ça sera même sûrement plus performant (quand bien même tu aurais pu faire des sous-requêtes).
    Et ensuite, dans la requête finale, tu fais ta jointure, avec un COUNT sur id_client et en groupant par nb_commandes.

    ced
    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

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

Discussions similaires

  1. Optimisation de votre SGBDR et de vos requêtes...
    Par SQLpro dans le forum Langage SQL
    Réponses: 35
    Dernier message: 11/01/2013, 11h49
  2. [Optimisation] Comment optimiser mon architecture ?
    Par buzzkaido dans le forum C++
    Réponses: 6
    Dernier message: 09/05/2007, 13h59
  3. [langage]Problème de temps de lecture, optimisation
    Par And_the_problem_is dans le forum Langage
    Réponses: 2
    Dernier message: 08/01/2003, 08h47
  4. [langage] Optimiser la lecture d'un fichier
    Par And_the_problem_is dans le forum Langage
    Réponses: 2
    Dernier message: 11/06/2002, 10h24

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