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 :

Distinct, group by et order by


Sujet :

Langage SQL

  1. #1
    Membre confirmé
    Inscrit en
    Mai 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 673
    Points : 624
    Points
    624
    Par défaut Distinct, group by et order by
    Voila, je dois faire un mini forum et affiché l'ordre des différents topics en fonction de la date du dernier post.
    Mes tables ressemblent grosso modo à ça :

    poste (id_poste, #auteur_poste, #sujet_poste, date_poste, texte_poste ) // post relatif à un topic
    sujet (id_sujet, #auteur_sujet, texte_sujet, date_sujet) // table des topics

    Mon problème est que je n'arrive pas à faire une requete qui puisse faire ce que je veux sans afficher autant de fois le sujet qu'il n'y a de reponse dedans...

    Si j'utilise la fonction DISTINCT dans mon select, absolument rien ne change par rapport à une requete ou je ne l'utilise pas. Si j'utilise GROUP¨BY, mon tri ne marche plus...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    // Requete ne tenant pas compte de l'ordre :
    select poste.date_poste, poste.sujet_poste, user.login_user, user.id_user from poste, user where user.id_user = poste.auteur_poste group by poste.sujet_poste order by poste.date_poste desc limit 0, 10 
     
    // requete tenant compte de l'ordre, mais affichant autant de fois le topic qu'il n'y a de réponse :
    select poste.date_poste, poste.sujet_poste, user.login_user, user.id_user from poste, user where user.id_user = poste.auteur_poste order by poste.date_poste desc limit 0, 10 
     
    // requete dont le résultat est strictement identique à celui de la requete précédente :
    select distinct poste.sujet_poste, poste.date_poste,  user.login_user, user.id_user from poste, user where user.id_user = poste.auteur_poste order by poste.date_poste desc limit 0, 10
    Nottez que j'ai enlevé la jointure avec la table USER pour plus de clareté dans la requete.

    Quelqun pourrait-il m'expliqué pourquoi cela ne marche pas ?
    Si vous avez un message d'erreur, n'oubliez pas de le lire, la réponse à votre problème est surement dedans !

  2. #2
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    Si tu veux afficher la liste des sujets, il faut utiliser la table des sujets, pas la table des posts (au passage il n'y a pas de e à post, et en français c'est message )

    Soit tu conserves ton modele actuel, mais dans ce cas là tu rajoutes une colonne à sujet qui stocke de manière interne la date du dernier message => optimisation au top

    Soit tu modifies ton modèle et tu n'utilise qu'une table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    messages(id, user_id, titre, texte, created_at, modified_at, parent_id)
    Où parent_id fait référence au message auquel il répond. Si c'est le sujet initial => 0

    Du coup ta requête deviendrait, pour afficher les "topics" :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM messages WHERE parent_id = 0 ORDER BY modified_at DESC
    Pour afficher le fil de discussion du "topic" 65 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT * FROM messages WHERE parent_id = 65 or id = 65 ORDER BY id

  3. #3
    Membre confirmé
    Inscrit en
    Mai 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 673
    Points : 624
    Points
    624
    Par défaut
    A vrai dire, la 1er méthode que j'avais utilisé était bien un select sur les sujets, et non sur les posts... de fil en aiguille au cours de mes tests, j'en suis arrivé a tester une méthode qui selectionne les posts, mais au final, je comprend toujours pas pourquoi le distinct ne fait rien et le group by annihile mon order by...

    Concernant l'optimisation par l'ajout d'un champs "modifie_le", je m'y refuse car si le gain en temps de calcul est réel, c'est contraire aux règles : on ne doit pas faire de redondance des données !

    De plus, contourner un problème me laissera dans mon ignorance.

    JE voudrais donc vraiment comprendre pourquoi ça ne marche pas...
    Si vous avez un message d'erreur, n'oubliez pas de le lire, la réponse à votre problème est surement dedans !

  4. #4
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    Dans ce cas, je ne vois pas d'autres solutions que d'utiliser les sous requetes.
    Un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT p1.sujet, p1. date
    FROM poste p1
    WHERE p1.date = (
       SELECT MAX(p2.date)
       FROM poste p2, p1
       WHERE p1.sujet = p2.sujet
    }
    ORDER BY p1.date DESC
    A corriger (je fais pas des sous requetes tous les jours) et à tester sur un SGBD qui supporte les requetes imbriquées...


    Quand aux règles... elles sont là pour être contournées (surtout quand les performances s'en mêlent)

  5. #5
    Membre confirmé
    Inscrit en
    Mai 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 673
    Points : 624
    Points
    624
    Par défaut
    je suis sur un SQL 4, et je crois que ça ne gère pas les sous requetes (pas avant sql5 je crois)... Je vous vois venir, vous allez donc me dire "bha tu fais 2 requetes en PHP ^^"...

    Mais bof...

    Disons que je viens ici pour essayer de comprendre... ce projet est un projet "perso", que je fait pour le plaisir, et quelque part, ça perd tout son interet si je m'amuse a contourner ce genre de choses.

    Donc sans essayer de contourner, pourquoi le group by annule l'effet du order by, et pourquoi le distinct ne change rien au résultat de ma requete ?
    Si vous avez un message d'erreur, n'oubliez pas de le lire, la réponse à votre problème est surement dedans !

  6. #6
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    Distinct sert à supprimer les doublons d'un résultats de requetes. Comme toutes les lignes sont différentes (la date n'est pas la meme) il n'y a pas de doublon, donc le distinct est inutile.

    Quand au group by, j'aurais tendance à dire que le order ne va s'appliquer qu'à un groupe. Je ne pense pas que le order soit vraiment adapté à un group by. A confirmer.

  7. #7
    Membre confirmé
    Inscrit en
    Mai 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 673
    Points : 624
    Points
    624
    Par défaut
    En effet, pour le distinct, c'est normal :p

    Dans ma requete d'origine, j'avais mis le distinct sur sujet.*, me disant que ça m'afficherai qu'une fois chaque sujet puisque le sujet ne change pas.
    Seulement, j'avais un truc du style

    select distinct sujet.*, poste.date, user.id_user, user.login_user from etc...

    Je pensais que le distinct ne s'appliqerai qu'a sujet.* et non pas a ce qui venait ensuite . Avais-je tort (je suppose puisque j'avais le même problème) ?
    Dans ce cas, quelle serait la vrai méthode propre en SQL ?
    Si vous avez un message d'erreur, n'oubliez pas de le lire, la réponse à votre problème est surement dedans !

  8. #8
    Expert éminent Avatar de Mr N.
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    5 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 5 418
    Points : 6 449
    Points
    6 449
    Par défaut
    Citation Envoyé par gloubi
    Je pensais que le distinct ne s'appliqerai qu'a sujet.* et non pas a ce qui venait ensuite . Avais-je tort (je suppose puisque j'avais le même problème) ?
    Oui. Distinct c'est pour tout une ligne.
    Dans ce cas, quelle serait la vrai méthode propre en SQL ?
    Sous requete

  9. #9
    Membre confirmé
    Inscrit en
    Mai 2002
    Messages
    673
    Détails du profil
    Informations forums :
    Inscription : Mai 2002
    Messages : 673
    Points : 624
    Points
    624
    Par défaut
    bon... puisqu'il le faut... va pour 2 requetes...
    Ca me frustre quand même cette méthode :p
    Si vous avez un message d'erreur, n'oubliez pas de le lire, la réponse à votre problème est surement dedans !

Discussions similaires

  1. GROUP BY and ORDER BY
    Par tsukasag dans le forum Langage SQL
    Réponses: 2
    Dernier message: 08/11/2009, 19h31
  2. Group by et order by
    Par LebronPA dans le forum Requêtes
    Réponses: 5
    Dernier message: 03/06/2009, 13h36
  3. Requête linq group by et order by
    Par LebronPA dans le forum Linq
    Réponses: 0
    Dernier message: 03/06/2009, 11h44
  4. [SQL] group by et order by dans la même requête ?
    Par thomfort dans le forum Langage SQL
    Réponses: 4
    Dernier message: 16/08/2007, 23h31
  5. [SQL] Jointure,Group BY et ORDER BY COUNT qui marche pas
    Par Stef784ever dans le forum Langage SQL
    Réponses: 8
    Dernier message: 17/08/2005, 13h28

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