Précédent   Forum des professionnels en informatique > Bases de données > MySQL > Requêtes
Requêtes Forum d'entraide sur les requêtes MySQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 10/03/2011, 00h36   #1
Invité de passage
 
Fred
Inscription : mars 2011
Messages : 3
Détails du profil
Informations personnelles :
Nom : Fred

Informations forums :
Inscription : mars 2011
Messages : 3
Points : 1
Points : 1
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 :
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:
Citation:
** 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 :
1
2
 
tupule5: 5  3         NULL   9 janv 2000
Le retour serait maintenant:
Citation:
** 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
fphenix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/03/2011, 09h31   #2
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 995
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
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 : 10 995
Points : 18 253
Points : 18 253
Envoyer un message via MSN à CinePhil
Essaie ceci :
Code :
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 de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« 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 Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est actuellement connecté   Envoyer un message privé Réponse avec citation 00
Vieux 10/03/2011, 17h52   #3
Invité de passage
 
Fred
Inscription : mars 2011
Messages : 3
Détails du profil
Informations personnelles :
Nom : Fred

Informations forums :
Inscription : mars 2011
Messages : 3
Points : 1
Points : 1
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 :
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).
fphenix est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 11/03/2011, 09h06   #4
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 995
Détails du profil
Informations personnelles :
Nom : Homme Philippe Leménager
Âge : 48
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 : 10 995
Points : 18 253
Points : 18 253
Envoyer un message via MSN à CinePhil
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 !

Citation:
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 :
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 de Formation Agronomique.
Mon blog sur la conception des BDD, le langage SQL, le PHP avec Zend Framework...
« 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 Mandriva Linux ou Mageïa ! Soutenons l'industrie logicielle française !
Linuxiens, comptez-vous !
CinePhil est actuellement connecté   Envoyer un message privé Réponse avec citation 10
Vieux 11/03/2011, 13h29   #5
Invité de passage
 
Fred
Inscription : mars 2011
Messages : 3
Détails du profil
Informations personnelles :
Nom : Fred

Informations forums :
Inscription : mars 2011
Messages : 3
Points : 1
Points : 1
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 :
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
fphenix est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 18h25.


 
 
 
 
Partenaires

Hébergement Web