2011-03-26 5 views
0

J'ai un tableau avec les colonnes, id, date, estValue & gradeid. Chaque identifiant contient environ 12 enregistrements et il y a environ 10 notes différentes pour un total d'environ 120 enregistrements. Je dois créer une sélection dans la base de données qui me donne un résultat qui ressemble à ceci:Complexe? Requête MySQL


date |gradeid1 |gradeid2 |gradeid3 3|etc... 
01/01/01|estValue1|estValue2||estValue3|etc.... 
01/01/02|estValue1|estValue2||estValue3|etc.... 

J'ai une requête qui peut sélectionner un enregistrement, mais je besoin de tous triés par date:


select eh.id, eh.date as wdate, 
    (select estValue from nas_estimatehistory where `date` like '2011-03-%' and gradeid = '1') as '1', 
    (select estValue from nas_estimatehistory where `date` like '2011-03-%' and gradeid = '2') as '2', 
    (select estValue from nas_estimatehistory where `date` like '2011-03-%' and gradeid = '3') as '3', 
    (select estValue from nas_estimatehistory where `date` like '2011-03-%' and gradeid = '4') as '4', 
    (select estValue from nas_estimatehistory where `date` like '2011-03-%' and gradeid = '5') as '5', 
    (select estValue from nas_estimatehistory where `date` like '2011-03-%' and gradeid = '6') as '6', 
    (select estValue from nas_estimatehistory where `date` like '2011-03-%' and gradeid = '7') as '7', 
    (select estValue from nas_estimatehistory where `date` like '2011-03-%' and gradeid = '8') as '8', 
    (select estValue from nas_estimatehistory where `date` like '2011-03-%' and gradeid = '9') as '9', 
    (select estValue from nas_estimatehistory where `date` like '2011-03-%' and gradeid = '10') as '10' 
from nas_estimatehistory eh 
group by wdate 
order by `wdate` asc 
limit 1; 

qui revient à peu près ce que j'ai besoin, mais seulement 1 rang, si je retire la limite, Je reçois une ligne pour chaque mois [12 lignes] mais toutes les valeurs des colonnes sont les mêmes [elles doivent toutes être différentes] c'est-à-dire estValue dans chaque ligne ET la colonne doit être une valeur unique ...

Je ne sais pas quelle est la meilleure façon d'y parvenir.

-Merci -Sean

+0

Le schéma de table (instructions de création) et les données d'exemple (présentées sous forme d'instructions SQL INSERT) sont très utiles dans des questions comme celles-ci. – outis

Répondre

1

Cross-tabulation est la clé: utiliser un aggregate function et la fonction IF.

SELECT eh.date AS wdate, 
    GROUP_CONCAT(IF(gradeid=1,estValue,NULL)) as `1`, 
    GROUP_CONCAT(IF(gradeid=2,estValue,NULL)) as `2`, 
    GROUP_CONCAT(IF(gradeid=3,estValue,NULL)) as `3`, 
    GROUP_CONCAT(IF(gradeid=4,estValue,NULL)) as `4`, 
    GROUP_CONCAT(IF(gradeid=5,estValue,NULL)) as `5`, 
    GROUP_CONCAT(IF(gradeid=6,estValue,NULL)) as `6`, 
    GROUP_CONCAT(IF(gradeid=7,estValue,NULL)) as `7`, 
    GROUP_CONCAT(IF(gradeid=8,estValue,NULL)) as `8`, 
    GROUP_CONCAT(IF(gradeid=9,estValue,NULL)) as `9`, 
    GROUP_CONCAT(IF(gradeid=10,estValue,NULL)) as `10` 
FROM nas_estimatehistory eh 
GROUP BY wdate 
ORDER BY `wdate` ASC; 

MAX ou MIN peuvent également être des fonctions d'agrégats appropriés.

+0

C'est précisément ce que je cherchais, c'est la tabulation croisée qui est documentée dans les docs MySQL, - ou est-ce plutôt une approche de type théorie [peut aussi apprendre quelque chose pendant que je suis là!] –

+0

Intéressant, il renvoie les valeurs sous forme d'objet blob, - je dois les convertir en chaînes pour que coldfusion les voie correctement, est-ce qu'il y a des choses à faire dans la requête elle-même? –

+0

@Sean: 'GROUP_CONCAT' ne devrait renvoyer un' BLOB' que si 'estValue' est une chaîne binaire (rendant le type de l'expression' IF() 'une chaîne binaire); changer 'estValue' en un type de texte non-binaire devrait prendre soin de cela. Voir la [documentation] (http://dev.mysql.com/doc/refman/5.1/fr/group-by-functions.html#function_group-concat) pour plus d'informations. Une autre option consiste à basculer sur 'MAX' ou' MIN', comme mentionné ci-dessus. – outis

0

Comme je l'ai dit, oublier la partie du groupe. Cela n'a aucun effet. Je pense que je vois votre problème.

Remplacer gradeid = '1' avec gradeid = eh.gradeid

+0

hmm. J'ai besoin que chaque rang soit d'un mois, chaque note a une valeur pour chaque mois ... Je ne suis pas sûr de ce que vous essayez de me dire. –

1
select eh.id, wdate, 
    (select estValue from nas_estimatehistory where `date` like `pattern` and gradeid = '1') as '1', 
    (select estValue from nas_estimatehistory where `date` like `pattern` and gradeid = '2') as '2', 
    (select estValue from nas_estimatehistory where `date` like `pattern` and gradeid = '3') as '3', 
    (select estValue from nas_estimatehistory where `date` like `pattern` and gradeid = '4') as '4', 
    (select estValue from nas_estimatehistory where `date` like `pattern` and gradeid = '5') as '5', 
    (select estValue from nas_estimatehistory where `date` like `pattern` and gradeid = '6') as '6', 
    (select estValue from nas_estimatehistory where `date` like `pattern` and gradeid = '7') as '7', 
    (select estValue from nas_estimatehistory where `date` like `pattern` and gradeid = '8') as '8', 
    (select estValue from nas_estimatehistory where `date` like `pattern` and gradeid = '9') as '9', 
    (select estValue from nas_estimatehistory where `date` like `pattern` and gradeid = '10') as '10' 
from (
    select eh.*, date_format(eh.date, '%Y-%m') wdate, 
       concat(date_format(eh.date, '%Y-%m'),'-%') `pattern` 
    from nas_estimatehistory) eh 
group by wdate 
order by wdate asc; 
+0

cela fonctionne aussi bien [petite correction nécessaire: de nas_estimatehistory hein] hein], plus facile pour moi de comprendre que la réponse de outis. –