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 03/12/2011, 16h08   #1
Invité de passage
 
Inscription : novembre 2008
Messages : 5
Détails du profil
Informations personnelles :
Localisation : France, Bas Rhin (Alsace)

Informations forums :
Inscription : novembre 2008
Messages : 5
Points : 1
Points : 1
Par défaut Utilisation de ANY sur une sélection d'identifiants aléatoires

Bonjour,

Je dispose d'un ensemble de tables pour stocker des chroniques de disques.
Ces tables se nomment ctx, disques, groupes, miroir.

Le stockage des informations suit deux schémas, selon que le disque chroniqué soit d'un type ou d'un autre. En gros :
- si mon disque est de type 1, alors la table disques contient les informations de base du disque, (label, date de sortie, nom, etc), la table groupes contient les informations sur le groupe qui a composé le disque (nom, origine, site web etc), et enfin la table ctx stocke toutes les chroniques qui ont été écrites pour ce disques (chronique, auteur de la chronique,date de rédaction, etc)
- si mon disque est de type 2, alors il n'existe qu'une seule table, la table miroir, qui stocke TOUTES les informations précédentes dans cette unique table (groupe, disque, chronique, label, date de sortie, date de redaction etc)

Voici un bref aperçu de la structure et des contraintes d'intégrité de mes tables afin de cerner le problème :

Citation:
TABLE ctx
CodeCtx (clef primaire)
#CodeChronique (clef étrangère -> disques.CodeChronique)
(...)
Citation:
TABLE disques
CodeChronique (clef primaire)
#CodeGroupe (clef étrangère -> groupes.CodeGroupe)
(...)
Citation:
TABLE miroir
CodeChronique (clef primaire)
(...)
Citation:
TABLE groupes
CodeGroupe (clef primaire)
(...)
De là, je cherche à faire, en une seule requête, la chose suivante :
- sélectionner les 20 chroniques les plus récentes se rapportant à un disque de type 1 (table ctx) et y adjoindre les informations qui vont bien (tables groupes et disques)
- sélectionner les 10 chroniques les plus récentes se rapportant à un disque de type 2 (table miroir uniquement)
- sélectionner au hasard une chronique de disque se rapportant à un disque de type 1 (table ctx) et y adjoindre les informations qui vont bien (tables groupes et disques)

MySql semble peu apprécier l'utilisation de LIMIT dans plusieurs requêtes UNIONées, aussi je recoure à du sous requêtage pour contourner le problème.

Ma requête actuelle se présente ainsi :

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
30
31
SELECT		CONCAT('../c/?d=',d.CodeChronique) AS "href",
		'' AS "classe",
		SUBSTR(c.TexteCtx,1,250) AS "texte",
		CONCAT(UPPER(g.NomGroupe),' - ',d.TitreDisque,' (',d.Label,', ',YEAR(d.Annee),')') AS "Titre",
		CONCAT('../img/pochettes/',d.Pochette) AS "pochette"
FROM		ctx c,
		disques d,
		groupes g
WHERE		g.CodeGroupe=d.CodeGroupe
AND		d.CodeChronique=c.CodeChronique
AND		d.CodeChronique>=(SELECT MAX(z.CodeChronique)-20 FROM disques z)
UNION
SELECT		CONCAT('../alice/?t=',m.CodeMiroir),
		'class="alice"',
		SUBSTR(TexteCtx,1,250),
		CONCAT(UPPER(m.NomGroupe),' - ',m.TitreDisque,' (',m.Label,', ',YEAR(Annee),')'),
		CONCAT('../img/pochettesm/',m.Pochette)
FROM 		miroir m
WHERE		m.CodeMiroir>=(SELECT MAX(y.CodeMiroir)-10 FROM miroir y)
UNION
SELECT		CONCAT('../c/?d=',d.CodeChronique),
		'class="vortex"',
		SUBSTR(c.TexteCtx,1,500),
		CONCAT(UPPER(g.NomGroupe),' - ',d.TitreDisque,' (',d.Label,', ',YEAR(Annee),')'),
		CONCAT('../img/pochettes/',d.Pochette)
FROM		ctx c,
		disques d,
		groupes g
WHERE		g.CodeGroupe=d.CodeGroupe
AND		d.CodeChronique=c.CodeChronique
AND		d.CodeChronique=ANY(SELECT x.CodeChronique FROM disques x ORDER BY RAND())
Impossible de faire un LIMIT 1 dans la dernière sous-requête (MySql ne l'admet pas), d'où l'utilisation de la fonction ANY.

Le résultat :
- conforme à l'attendu pour le premier SELECT
- conforme à l'attendu pour le second SELECT
- conforme pour le dernier SELECT, qui renvoie tous les enregistrements

Pour pallier ce désagrément je rajoute à la fin de la requête sur l'ensemble du résultat, ainsi je ne conserve que le nombre d'enregistrements attendu.

Le problème :
La dernière requête renvoie les enregistrements triés sur le CodeChronique, et non aléatoirement.
Je ne sais pas si le dysfonctionnement de l'aléatoire provient de la dernière sous-requête ou du comportement du ANY en lui-même, que je ne comprends pas tout à fait (prend-il le plus petit enregistrement de la liste en premier ? Le premier de la liste en premier ?)

Si quelqu'un a une autre idée pour réaliser cette requête (sans la découper en plusieurs requêtes sans UNION), je suis toutes ouïes

Merci.
Rocky Turquoise 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 18h03.


 
 
 
 
Partenaires

Hébergement Web