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 28/02/2011, 19h39   #1
Futur Membre du Club
 
Damien
Inscription : juillet 2009
Messages : 50
Détails du profil
Informations personnelles :
Nom : Damien

Informations forums :
Inscription : juillet 2009
Messages : 50
Points : 16
Points : 16
Par défaut Optimisation d'une requête

Bonjour,

Je reviens cette fois non pas pour une requête qui ne marche pas mais pour une requête qui me fait blêmir...

Son but (ou le mien) : récupérer les topics d'un forum (ici les 10 premiers pour l'exemple), agrémentés d'informations telles que l'id, le nom, prenom du premier posteur (donc createur du topic) et du dernier posteur.

Âmes sensibles fermez les yeux, je mets le code

Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
SELECT T.topic_id, T.topic_titre, MAX(P.post_id) AS last_post_id, MAX(P.post_date) AS last_post_date,
U.user_id AS first_user_id, U.user_nom AS first_user_nom, U.user_prenom AS first_user_prenom, 
(
	SELECT user_id FROM users WHERE user_id = 
	(
		SELECT user_id FROM posts WHERE topic_id = P.topic_id ORDER BY post_date DESC LIMIT 0, 1
	)
) AS last_user_id,
(
	SELECT user_prenom FROM users WHERE user_id = 
	(
		SELECT user_id FROM posts WHERE topic_id = P.topic_id ORDER BY post_date DESC LIMIT 0, 1
	)
) AS last_user_prenom,
(
	SELECT user_nom FROM users WHERE user_id = 
	(
		SELECT user_id FROM posts WHERE topic_id = P.topic_id ORDER BY post_date DESC LIMIT 0, 1
	)
) AS last_user_nom
FROM topics T 
LEFT JOIN posts P ON P.topic_id = T.topic_id 
LEFT JOIN users U ON U.user_id = P.user_id
WHERE forum_id = $forumId ORDER BY P.post_date DESC LIMIT 0, 10
Si ça peut aider, je met aussi la forme des tables :

Topics : topic_id, topic_titre, topic_date (creation), forum_id
Posts : post_id, post_content, post_date, post_date_edit, user_id, topic_id
Users : user_id, user_nom, user_prenom, [...]

Voilou, j'imagine bien que ma solution est tout sauf optimiser, donc si quelqu'un connait une solution plus sympathique... (Autre que rajouter la colonne 'last_post_id' dans la table 'topics' ^^)

Merci d'avance à ceux qui liront !
WibiMaster est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/03/2011, 16h36   #2
Modérateur
 
Avatar de CinePhil
 
Homme Philippe Leménager
Ingénieur d'études en informatique
Inscription : août 2006
Messages : 10 993
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 993
Points : 18 246
Points : 18 246
Envoyer un message via MSN à CinePhil
Citation:
récupérer les topics d'un forum (ici les 10 premiers pour l'exemple), agrémentés d'informations telles que l'id, le nom, prenom du premier posteur (donc createur du topic) et du dernier posteur.
Vu que, dans ta requête, tu as classé par date de post descendante, tu veux plutôt les dix derniers posts ou les dix premiers topics ?

1) Dates du premier et du dernier post de chaque topic du forum :
Code :
1
2
3
4
5
6
7
SELECT t.topic_id, t.topic_titre, t.topic_date,
    MIN(p.post_date) AS date_premier_post
    MAX(p.post_date) AS date_dernier_post
FROM Topics t
INNER JOIN Posts p ON p.topic_id = t.topic_id
WHERE t.forum_id = $forumId
GROUP BY t.topic_id, t.topic_titre, t.topic_date
2) Identifiant du premier et du dernier posteur de chaque topic du forum :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
SELECT 
    p1.post_id AS id_premier_post,
    p1.user_id AS id_premier_posteur,
    p2.post_id AS id_dernier_post,
    p2.user_id AS id_dernier_posteur,
    tmp.topic_id, tmp.topic_titre, tmp.topic_date,
    tmp.date_premier_post, tmp.date_dernier_post
FROM 
(
    SELECT t.topic_id, t.topic_titre, t.topic_date,
        MIN(p.post_date) AS date_premier_post
        MAX(p.post_date) AS date_dernier_post
    FROM Topics t
    INNER JOIN Posts p ON p.topic_id = t.topic_id
    WHERE t.forum_id = $forumId
    GROUP BY t.topic_id, t.topic_titre, t.topic_date
) tmp
INNER JOIN Posts p1 
    ON p1.topic_id = tmp.topic_id
    AND p1.post_date = tmp.date_premier_post
INNER JOIN Posts p2
    ON p2.topic_id = tmp.topic_id
    AND p2.post_date = tmp.date_dernier_post
3) On ajoute l'identité des posteurs par deux jointures avec la table Users :
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
SELECT 
    p1.post_id AS id_premier_post,
    p1.user_id AS id_premier_posteur,
    p2.post_id AS id_dernier_post,
    p2.user_id AS id_dernier_posteur,
    tmp.topic_id, tmp.topic_titre, tmp.topic_date,
    tmp.date_premier_post, tmp.date_dernier_post,
    u1.nom AS nom_premier_posteur,
    u1.prenom AS prenom_premier_posteur,
    u2.nom AS nom_dernier_posteur
    u2.prenom AS prenom_dernier_posteur
FROM 
(
    SELECT t.topic_id, t.topic_titre, t.topic_date,
        MIN(p.post_date) AS date_premier_post
        MAX(p.post_date) AS date_dernier_post
    FROM Topics t
    INNER JOIN Posts p ON p.topic_id = t.topic_id
    WHERE t.forum_id = $forumId
    GROUP BY t.topic_id, t.topic_titre, t.topic_date
) tmp
INNER JOIN Posts p1 
    ON p1.topic_id = tmp.topic_id
    AND p1.post_date = tmp.date_premier_post
    INNER JOIN Users u1 ON u1.user_id = p1.user_id
INNER JOIN Posts p2
    ON p2.topic_id = tmp.topic_id
    AND p2.post_date = tmp.date_dernier_post
    INNER JOIN Users u2 ON u2.user_id = p2.user_id
__________________
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 déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 14h27.


 
 
 
 
Partenaires

Hébergement Web