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 dans la même table avec ORDER BY et GROUP BY


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Avril 2015
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste d'exploitation
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2015
    Messages : 33
    Points : 18
    Points
    18
    Par défaut Jointure dans la même table avec ORDER BY et GROUP BY
    Bonjour tous le monde,

    Je le précise tout de suite que le sql n'est pas mon point fort et que je galère assez bien pour une requête, explications:

    J'ai une table "disc" avec les colonnes suivantes :
    id, pseudo, message, correspondant, niveau, cle, lu_correspondant

    La colonne "niveau" prend comme valeur, "parametre" OU "discussion".

    En résumé, lorsqu'un utilisateur s'inscrit dans la discussion, une ligne est crée pour les paramètres de l'utilisateur et lorsque cette personne envoi un message,une ligne est crée avec comme valeur "discussion" dans la colonne : "niveau"

    J'aimerais dans la même requête, récupérer la clé de la ligne de paramètre et récupérer les messages non lus.

    J'ai fais une requête mais le problème est l'ordre d'affichage des résultats :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $resultat = $wpdb->get_results("SELECT A.pseudo, A.message, B.cle FROM ".$wpdb->prefix."disc A JOIN ".$wpdb->prefix."disc B ON (B.pseudo=A.pseudo) WHERE (B.niveau='parametre' AND A.lu_correspondant='0' AND A.correspondant='$pseudo' AND A.message!='' AND A.niveau='discussion') GROUP BY A.pseudo ORDER BY A.id DESC");
    Résultat :

    1 Lolo test
    2 Shuter bonjour


    Et dans la table, le contenu est :
    1 Lolo test
    2 Shuter bonjour
    3 Lolo tu vas bien ?
    4 Shuter sa va ?


    J'aimerais que mes résultats apparaissent ainsi :
    3 Lolo tu vas bien
    4 Shuter sa va ?


    J'ai déjà essayé plein de truc mais sans succès, si vous avez une solution je suis preneur, merci d'avoir lu jusqu'ici

  2. #2
    Membre éclairé Avatar de bstevy
    Homme Profil pro
    Solutions Architect
    Inscrit en
    Mai 2009
    Messages
    552
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Japon

    Informations professionnelles :
    Activité : Solutions Architect
    Secteur : Finance

    Informations forums :
    Inscription : Mai 2009
    Messages : 552
    Points : 870
    Points
    870
    Par défaut
    Bah, ca sent le mysql tout ca ^^

    essayez déjà sans le group by, car un group by sans fonction d'agrégation, ca sert à rien ^^
    Ensuite, si vous ramenez les messages lu, c'est qu'il doit y avoir un problème dans votre where. vous devriez revoir un peu vos conditions pour ne selectionner justement que les messages lus.

    Votre ordre by n'aura comme intéret à la fin que d'afficher vos données dans l'ordre du plus vieux au plus récént je pense, il ne devrait avoir aucune influence sur votre jeu de données, donc ne le mettez pas tant que vous n'êtes pas sur du résultat que vous optenez.

    Si y'a un truc pas clair, hésitez pas à demander.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Avril 2015
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste d'exploitation
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2015
    Messages : 33
    Points : 18
    Points
    18
    Par défaut
    Bonjour bstevy,

    Merci pour ta réponse, j'avais déjà essayé en retirant GROUP BY mais dans ce cas là je récupère tous les messages non lus et j'aimerais ne récupérer que le dernier message non lu par utilisateur.
    Ma requête devient ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    $resultat = $wpdb->get_results("SELECT A.pseudo, A.message, B.cle 
    FROM ".$wpdb->prefix."disc A JOIN ".$wpdb->prefix."disc B ON (B.pseudo=A.pseudo) 
    WHERE (B.niveau='parametre' AND A.lu_correspondant='0' AND A.correspondant='$pseudo' AND A.message!='' AND A.niveau='discussion')  
    ORDER BY A.pseudo DESC");
    Et j’obtiens les résultats ainsi :

    1 Lolo test
    3 Lolo tu vas bien ?
    2 Shuter bonjour
    4 Shuter sa va ?

    Et j'aimerais donc les avoirs ainsi :
    3 Lolo tu vas bien ?
    4 Shuter sa va ?

    Ma question est donc comment limiter au dernier message par pseudo ?

  4. #4
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 184
    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 184
    Points : 12 733
    Points
    12 733
    Par défaut
    Bonjour,
    Je dirai que le dernier est celui pour lequel il n'y en a pas avec un Id/une date/autre qui soit supérieur, et avec le même Id.
    Ca se résout avec une sous-requête, une jointure externe... ce sujet a déjà été abordé maintes fois sur le forum.

    Tatayo.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Avril 2015
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste d'exploitation
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2015
    Messages : 33
    Points : 18
    Points
    18
    Par défaut
    Bonjour,

    Si je me suis permis de poster ma question sur ce forum, c'est que j'ai déjà pris plusieurs jours à trouver une solution, lecture de documentation... En vain.

    Les jointures externes et les sous requêtes peuvent permettre de faire ça mais partout ou j'ai vu l'usage des jointures, c'était pour récupérer l'intégralité de 2tables.

    Pour finir, merci tatayo pour votre participation mais vous dites que le sujet a été abordé maintes fois, dans ce cas je suis preneur pour des exemples similaires.

    En résumé je suis toujours au même point qu'il y a 3jours, j'attends donc des réponses constructives pour permettre de trouver une solution à mon problème et aussi permettent à ceux confrontés au même problème de trouver une solution leur permettant d'éviter de poster.

    Merci encore

  6. #6
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 763
    Points
    30 763
    Par défaut
    Le cas classique :
    Identifier la dernière facture de chaque client.

    La table :
    facture(no_fact, client, dt_fact)

    La requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    select  fct.no_fact
        ,   fct.client
        ,   fct.dt_fact
    from    facture fct
        inner join
            (   select  client
                    ,   max(dt_fact)    as  dt_fact
                from    facture
                group by client
            )   dat
            on  fct.client  = dat.client
            and fct.dt_fact = dat.dt_fact
    Reste plus qu'à adapter à ton besoin
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Responsable Données
    Inscrit en
    Janvier 2009
    Messages
    5 184
    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 184
    Points : 12 733
    Points
    12 733
    Par défaut
    Ou sans sous-requête:
    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    select f1.*
    from facture f1
    left outer join facture f2 on f2.client = f1.client and f2.dt_client > f1.dt_client
    where F2.id is null
    Je prends comme hypothèse que dt_client est un timestamp, et qu'on ne peut pas avoir 2 factures avec le même timestamp...

    Tatayo.

  8. #8
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

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

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 763
    Points
    30 763
    Par défaut
    On peut aussi le faire avec une restriction sur une sous-requête corrélée
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    select  fct.no_fact
        ,   fct.client
        ,   fct.dt_fact
    from    facture fct 
    where   exists
            (   select  null
                from    facture dat
                where   fct.client  = dat.client
                having  fct.dt_fact = max(dat.dt_fact)
            )
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  9. #9
    Membre à l'essai
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Avril 2015
    Messages
    33
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste d'exploitation
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2015
    Messages : 33
    Points : 18
    Points
    18
    Par défaut [Résolu]
    J'ai enfin trouvé la solution grâce à vous, je ne sais pas si c'est la meilleure mais elle me permet d'avoir ce que j'attendais.

    Voici ma requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    $resultat = $wpdb->get_results("SELECT TB1.pseudo, TB1.message, TBC.cle FROM ".$wpdb->prefix."disc
     TB1 JOIN ".$wpdb->prefix."disc TBC ON TB1.pseudo=TBC.pseudo AND TBC.niveau='parametre' 
    WHERE EXISTS (SELECT NULL FROM ".$wpdb->prefix."disc TB2 WHERE (TB2.pseudo=TB1.pseudo)
     HAVING TB1.heure = max(TB2.heure)) AND TB1.lu_correspondant='0' AND TB1.message!='' AND TB1.correspondant='$pseudo'");
    Un grand merci à tous pour vos exemples, je considère ce post comme résolu, bonne fin de journée.

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

Discussions similaires

  1. Jointure sur un même table avec utilisation MIN/MAX
    Par Chips_ dans le forum Requêtes
    Réponses: 4
    Dernier message: 13/12/2012, 15h29
  2. Réponses: 6
    Dernier message: 10/11/2012, 00h18
  3. Jointure dans une même table
    Par NemoParis dans le forum Débutez
    Réponses: 9
    Dernier message: 01/06/2010, 16h17
  4. [MySQL] requête avec jointure sur la même table
    Par gwena54 dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 08/05/2007, 12h22

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