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 :

ordonner les parents par rapport aux dates des children


Sujet :

Requêtes MySQL

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 3
    Points : 3
    Points
    3
    Par défaut ordonner les parents par rapport aux dates des children
    Bonjour à tous,

    Relativement nouveau dans le monde de MySQL, je butte sur le problème suivant malgré la lecture de nombreux tuto/forum/etc.

    Voici un exemple simplifié de ce que j'essaye de faire:

    J'ai une table comme suit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    champs:  id parent_id titre cdate       (msg author_id ...)
    tupule1: 1  NULL      TA    1 janv 2000 (...)
    tupule2: 2  1         NULL  3 janv 2000 (...)
    tupule3: 3  NULL      TB    5 janv 2000 (...)
    tupule4: 4  1         NULL  7 janv 2000 (...)
    je souhaite un retour qui ne liste que les "Parents" (c'est à dire parent_id IS NULL) mais triés par ordre anti-chronologique de la mise-à-jour (ou de la réponse) associée la plus récente.

    Par exemple ici un retour serait:
    ** TA crée le 1 janv 2000; maj le 7 janv 2000
    ** TB crée le 5 janv 2000;
    admettons que l'on ajoute:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    tupule5: 5  3         NULL   9 janv 2000
    Le retour serait maintenant:
    ** TB crée le 5 janv 2000; maj le 9 janv 2000
    ** TA crée le 1 janv 2000; maj le 7 janv 2000
    Je souhaite une requête unique (avec éventuellement des sous-requêtes si nécessaire). J'ai essayé diverses options avec UNION, LEFT JOIN, CREATE TEMPLATE, GROUP BY, etc. pour le moment rien ne me satisfait car je dois re-traiter sous php après.

    Je m'en remets donc à votre expertise! Merci.

    Fred

  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 : 60
    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 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Essaie ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT t1.titre, 
        t1.cdate AS 'Créé le',
        MAX(t2.cdate) AS 'Mis à jour le'
    FROM la_table t1
    LEFT OUTER JOIN la_table t2 ON t2.parent_id = t1.id
    GROUP BY t1.titre, MAX(t2.cdate)
    ORDER BY MAX(t2.cdate)
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Merci Philippe de vous intéresser à ce problème.

    Le code proposé me retourne un "Utilisation invalide de la clause GROUP".
    (après quelques infructueux essais avec HAVING) J'ai tenté avec:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT t1.titre AS tit, 
    t1.cdate AS cdate,
    MAX(t2.cdate) AS maj
    FROM tab AS t1
    LEFT OUTER JOIN tab AS t2
    ON t2.parent_id = t1.id
    WHERE t1.titre IS NOT NULL
    GROUP BY tit 
    ORDER BY maj
    Ce n'est pas si loin, mais sur l'exemple que j'ai utilisé, les items ne sont pas triés comme souhaité. Ma difficulté est de trier sur l'ordre de création du parent (cdate) sauf si un "child" existe, en quel cas c'est la date du plus récent child (ou de la plus récente mise-à-jour liée) qui est utilisée pour classer.

    A propos, je n'ai pas mentionné l'environnement: EasyPhp 5.3.5.0 (MySQL 5.1.54).

  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 : 60
    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 031
    Points
    34 031
    Billets dans le blog
    14
    Par défaut
    Citation Envoyé par fphenix Voir le message
    Le code proposé me retourne un "Utilisation invalide de la clause GROUP".
    Effectivement, grosse bourde dans ma requête !
    Une fonction de regroupement dans le GROUP BY, c'est le serpent qui se mord la queue à force de se demander qui de l'oeuf ou de la poule est arrivé en premier !

    trier sur l'ordre de création du parent (cdate) sauf si un "child" existe, en quel cas c'est la date du plus récent child (ou de la plus récente mise-à-jour liée) qui est utilisée pour classer.
    Essaie cette requête :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT t1.titre, 
        t1.cdate AS 'Créé le',
        MAX(t2.cdate) AS 'Mis à jour le'
    FROM la_table t1
    LEFT OUTER JOIN la_table t2 ON t2.parent_id = t1.id
    GROUP BY t1.titre, t1.cdate
    ORDER BY 
        CASE
            WHEN t2.parent_id IS NULL THEN t1.cdate
            ELSE MAX(t2.cdate)
        END
    Philippe Leménager. Ingénieur d'étude à l'École Nationale Supérieure de Formation de l'Enseignement Agricole. Autoentrepreneur.
    Mon ancien blog sur la conception des BDD, le langage SQL, le PHP... et mon nouveau blog sur les mêmes sujets.
    « Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément ». (Nicolas Boileau)
    À la maison comme au bureau, j'utilise la suite Linux Mageïa !

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Mars 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2011
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Merci Philippe!

    La solution donnée est quasiment parfaite en l'état et j'ai pu la finaliser dans mon cas précis.
    En effet, j'ai juste eu à ajouter le "WHERE" pour filtrer des lignes vides (en fait tous les "children") qui m'étaient retournées et un "DESC" à la fin pour choisir le sens du tri.

    Soit au final: (note: noms de champs sont légèrement changés)

    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
     
    SELECT t1.t_title AS tit, 
    	   t1.t_date AS cdate,
               MAX(t2.t_date) AS maj
    FROM tab AS t1
    LEFT OUTER JOIN tab AS t2
        ON t2.t_pid = t1.t_id
    WHERE t1.t_pid IS NULL
    GROUP BY t1.t_title , t1.t_date
    ORDER BY 
         CASE
              WHEN t2.t_pid IS NULL THEN t1.t_date
              ELSE MAX(t2.t_date)
         END
         DESC
    J'avais justement considéré utiliser "CASE" hier soir, mais je n'avais à ce stade pas encore compris que l'on pouvait l'utiliser dans le "ORDER BY".

    Merci encore! Depuis plusieurs jours que je planche là dessus, je ne m'attendais pas à une solution si "simple"!

    --Fred

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

Discussions similaires

  1. Position des QLabel les uns par rapport aux autres
    Par dharkan dans le forum Débuter
    Réponses: 4
    Dernier message: 23/04/2011, 18h21
  2. Placer des table les unes par rapport aux autres.
    Par IyF33 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 13
    Dernier message: 03/07/2008, 09h29
  3. Réponses: 4
    Dernier message: 16/01/2008, 10h08
  4. Numeroter les tables par rapport aux contraintes
    Par nicassy dans le forum Outils
    Réponses: 10
    Dernier message: 02/02/2007, 11h39
  5. Regrouper les données par rapport à la date
    Par goldeagle dans le forum Access
    Réponses: 7
    Dernier message: 11/12/2006, 15h35

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