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 :

Petit souci sur requête mysql


Sujet :

Langage SQL

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2007
    Messages : 9
    Points : 4
    Points
    4
    Par défaut Petit souci sur requête mysql
    Bonjour à tous !
    J'aurai besoin de votre aide sur une requête mysql que voici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT c2.customers_firstname AS Prenom, c2.customers_lastname AS Nom, c2.customers_email_address AS Adresse_mail, c4.customers_info_date_account_created AS DateCreationCompte, COUNT( c1.orders_id ) AS NbCommandes, c1.date_purchased AS DateCommande1, c5.value AS MontantCommande
    FROM orders c1, BDD1 c2, customers c3, customers_info c4, orders_total c5
    WHERE c2.customers_email_address = c3.customers_email_address
    AND c1.customers_id = c3.customers_id
    AND c3.customers_id = c4.customers_info_id
    AND c5.class = "ot_total"
    AND c5.orders_id = c1.orders_id
    GROUP BY c2.customers_lastname
    LIMIT 0 , 30;
    Grâce à "COUNT( c1.orders_id )" je sais qu'un des clients à fait plusieurs commandes. Et j'aimerai afficher toutes les dates de "passage de commande" (c1.date_purchased) ainsi que tous les montants de ces commandes (c5.value).
    Seulement, je ne sais pas trop pourquoi ça ne m'affiche à chaque fois que les infos de la première commande.
    Pourriez-vous m'aider ou me mettre sur la voie s'il vous plaît ?
    Kisa

  2. #2
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    On va procéder par étape et utiliser les jointures normalisées...

    Grâce à "COUNT( c1.orders_id )" je sais qu'un des clients à fait plusieurs commandes. Et j'aimerai afficher toutes les dates de "passage de commande" (c1.date_purchased) ainsi que tous les montants de ces commandes (c5.value).
    Si je traduis correctement, vous souhaitez afficher les dates de passage de commande et les montants de ces commandes pour les clients qui ont passé plus d'une commande ?

    Cherchons d'abord les clients qui ont passé plusieurs commandes :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT c3.customers_id, 
        c2.customers_firstname AS Prenom, c2.customers_lastname AS Nom, c2.customers_email_address AS Adresse_mail,
        c4.customers_info_date_account_created AS DateCreationCompte
    FROM customers c3
    INNER JOIN orders c1 ON c1.customers_id = c3.customers_id
    INNER JOIN BDD1 c2 ON c2.customers_email_address = c3.customers_email_address
    INNER JOIN customers_info c4 ON c3.customers_id = c4.customers_info_id
    GROUP BY c3.customers_id, c2.customers_firstname, c2.customers_lastname, c2.customers_email_address, c4.customers_info_date_account_created
    HAVING COUNT(c1.*) > 1
    Utilisons maintenant ce résultat en tant que sous requête pour faire la jointure avec les commandes :
    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
    SELECT tmp.Prenom, tmp.Nom, tmp.Adresse_mail, tmp.DateCreationCompte,
        c1.date_purchased AS DateCommande1, c5.value AS MontantCommande
    FROM orders c1
    INNER JOIN 
    (
        SELECT c3.customers_id, 
        c2.customers_firstname AS Prenom, c2.customers_lastname AS Nom, c2.customers_email_address AS Adresse_mail,
        c4.customers_info_date_account_created AS DateCreationCompte
        FROM customers c3
        INNER JOIN BDD1 c2 ON c2.customers_email_address = c3.customers_email_address
        INNER JOIN customers_info c4 ON c3.customers_id = c4.customers_info_id
        GROUP BY c3.customers_id, c2.customers_firstname, c2.customers_lastname, c2.customers_email_address, c4.customers_info_date_account_created
        HAVING COUNT(c1.*) > 1
    ) tmp ON c1.customers_id = tmp.customers_id
    INNER JOIN orders_total c5 ON c5.orders_id = c1.orders_id
    WHERE c5.class = 'ot_total'
    Au passage, une jointure sur une adresse mail c'est pas terrible !

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2007
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    Merci beaucoup pour votre réponse, j'étudie le code car j'avoue que je ne connaissais pas ces histoires de "tmp" et tout...
    En essayant de le lancer sur phpmyadmin, il me met une erreur :

    "#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '* ) > '1' ) tmp ON c1 . customers_id = tmp . customers_id INNER JOIN orders_to' at line 1 "
    J'ai essayé de mettre le 1 entre guillemets car je crois que c'est lui qui fait buguer mais ça n'a pas marché...

    Ps: oui, la jointure sur adresse mail n'est pas très bien ^^" Mais il n'y a pas d'id sur la table BDD1.

  4. #4
    Modérateur

    Avatar de CinePhil
    Homme Profil pro
    Ingénieur d'études en informatique
    Inscrit en
    Août 2006
    Messages
    16 799
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur d'études en informatique
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2006
    Messages : 16 799
    Points : 34 048
    Points
    34 048
    Billets dans le blog
    14
    Par défaut
    Essaie avec HAVING COUNT(*) > 1 Mais vérifie avec des cas concrets ou des jeux de test que ça vous donne le bon résultat.

    Ps: oui, la jointure sur adresse mail n'est pas très bien ^^" Mais il n'y a pas d'id sur la table BDD1.
    Ben ça c'est pas bien !
    Si vous avez la maîtrise de la structure de la base, il serait judicieux d'en mettre un.

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2007
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    Oui, j'ai essayé du coup, et la requête fonctionne.
    Malheureusement même si une personne a plusieurs commandes, ces dernières ne s'affichent pas.
    MErci en tout cas pour votre aide ! J'essaierai d'en parler avec le "chef" pour voir si je peux toucher à leur base de données

  6. #6
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2007
    Messages : 9
    Points : 4
    Points
    4
    Par défaut Deuxième problème XD
    Ca y est ! La requête fonctionne et j'arrive à afficher le nombre de commandes et le détails de ces commandes :

    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
    SELECT c.customers_lastname AS Nom, c.customers_firstname AS Prenom, c.customers_email_address AS AdresseMail, c4.customers_info_date_account_created AS DateCreationCompte, o.date_purchased AS Date_Commmande, ot.value AS Montant, c5.NbCommandes
    FROM customers c, orders o, orders_total ot, customers_info c4, (
     
    SELECT COUNT( * ) AS NbCommandes, customers_id
    FROM orders
    GROUP BY customers_id
    )c5
    WHERE o.customers_id = c.customers_id
    AND c4.customers_info_id = c.customers_id
    AND c5.customers_id = c.customers_id
    AND c.customers_email_address
    IN (
     
    SELECT customers_email_address
    FROM OptinSolution031208a161208
    )
    AND o.orders_id = ot.orders_id
    AND ot.class = 'ot_total'
    ORDER BY c.customers_lastname ASC
    Par contre, j'aimerai aussi afficher les personnes qui ont créé un compte, mais pas forcément fait une commande...
    Comment faire sachant que je crois être "obligée" de faire cette jointure :
    "WHERE o.customers_id = c.customers_id"

    Si quelqu'un aurait une petite idée ?

    MErci d'avance en tout cas !

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 849
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 849
    Points : 52 978
    Points
    52 978
    Billets dans le blog
    6
    Par défaut
    Il suffit de faire une jointure externe : http://sqlpro.developpez.com/cours/s...ntures/#LIII-C

    A +

  8. #8
    Candidat au Club
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    9
    Détails du profil
    Informations personnelles :
    Âge : 36
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Avril 2007
    Messages : 9
    Points : 4
    Points
    4
    Par défaut
    Je ne connaissais pas non plus XD Merci SQLpro !
    Par contre, "comme d'habitude", j'ai une erreur...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Documentation
    #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FULL OUTER JOIN orders O  ON o . customers_id = c . customers_id  AND c4 . custo' at line 1
    Je fais :

    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
    SELECT c.customers_lastname AS Nom, c.customers_firstname AS Prenom, c.customers_email_address AS AdresseMail, c4.customers_info_date_account_created AS DateCreationCompte, o.date_purchased AS Date_Commmande, ot.value AS Montant, c5.NbCommandes
    FROM orders o, orders_total ot, customers c, customers_info c4, (
     
    SELECT COUNT( * ) AS NbCommandes, customers_id
    FROM orders
    GROUP BY customers_id
    )c5,  FULL OUTER JOIN orders o
    ON o.customers_id = c.customers_id
     
    WHERE c.customers_email_address
    IN (
    SELECT customers_email_address
    FROM OptinSolution031208a161208
    )
     
    AND c4.customers_info_id = c.customers_id
    AND c5.customers_id = c.customers_id
    AND o.orders_id = ot.orders_id
    AND ot.class = 'ot_total'
    ORDER BY c.customers_lastname ASC

  9. #9
    Membre émérite Avatar de pacmann
    Homme Profil pro
    Consulté Oracle
    Inscrit en
    Juin 2004
    Messages
    1 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Consulté Oracle
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2004
    Messages : 1 626
    Points : 2 845
    Points
    2 845
    Par défaut
    Salut !

    FULL OUTER JOIN n'est pas implémenté par MySQL.
    Pour faire une jointure FULL, tu dois faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT *
    FROM Table1 a LEFT OUTER JOIN Table2 b
      ON ...
    UNION ALL
    SELECT *
    FROM Table1 a LEFT OUTER JOIN Table2 b
      ON ...
    WHERE a.id IS NULL
    En gros, quand tu dis je veux toutes les lignes de la jointure + les orphelins "à gauche" + les orphelins "à droite", tu peux décomposer en deux étapes, et chercher les orphelins à droite séparément. (Marche également avec NOT EXISTS pour la deuxième requête)

Discussions similaires

  1. Réponses: 1
    Dernier message: 02/01/2008, 13h28
  2. petit soucis sur les types
    Par 20100. dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 14/12/2007, 20h55
  3. petit souci sur cadre d'options
    Par tibiurs dans le forum Access
    Réponses: 7
    Dernier message: 24/08/2006, 11h21
  4. [C#] Petit soucis sur un TreeView ...
    Par hobotalker dans le forum Windows Forms
    Réponses: 8
    Dernier message: 29/11/2005, 15h33
  5. Petit souci sur la libération d'une connexion tcp
    Par alexandre75 dans le forum Développement
    Réponses: 1
    Dernier message: 08/11/2005, 19h43

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