Premier résultat par date en tant que colonnes par élément unique

J'ai un tableau de données recueillies au fil du time dans le format suivant:

Title | Date | Value ----------------------- test1 | 2015-09-18 | 99 test1 | 2015-09-02 | 97 test1 | 2015-08-31 | 101 test1 | 2015-08-03 | 11 test1 | 2015-07-20 | 100 test2 | 2015-09-05 | 102 test2 | 2015-09-04 | 101 test2 | 2015-08-22 | 91 test2 | 2015-07-19 | 76 test2 | 2015-07-12 | 66 

Je voudrais être en mesure de produire le dernier résultat pour chaque mois en colonnes pour chaque valeur distincte. Les en-têtes de colonnes (Sept, Août, Juillet) ne sont pas importants en passant. Il y aura toujours un timeout de 3 mois.

 Title | Sept | Aug | July ---------------------------- test1 | 99 | 101 | 100 test2 | 102 | 91 | 76 

Est-ce possible? J'ai pensé à l'utilisation de CTE mais je suis un peu confus quant à la prochaine étape.

Toute aide / conseil est appréciée!

Vous pouvez utiliser un CTE pour préparer un set de résultats pour le SELECT actuel.

 WITH cte AS ( SELECT Title, MAX([Date]) d, ROW_NUMBER() OVER( PARTITION BY Title ORDER BY DATEFROMPARTS(YEAR([Date]), MONTH([Date]), 1) DESC) rn FROM t1 GROUP BY Title, DATEFROMPARTS(YEAR([Date]), MONTH([Date]), 1) ) SELECT t.Title, MAX(CASE WHEN cte.rn = 1 THEN t.Value END) m1, MAX(CASE WHEN cte.rn = 2 THEN t.Value END) m2, MAX(CASE WHEN cte.rn = 3 THEN t.Value END) m3 FROM cte INNER JOIN t1 t ON t.Title = cte.Title AND t.[Date] = cte.d GROUP BY t.Title 

Voir travailler SQLFiddle

* Remarque: Cela ne prendra que les 3 derniers mois de données par "Titre", mais ne sera pas aligné si, par exemple, le dernier mois de test1 est en septembre et le dernier mois de test2 est en août.

Faites un GROUP BY , utilisez CASE pour faire MAX conditionnel pour chaque mois désiré.

 select title, max(case when Month(Date) = 9 then value end), max(case when Month(Date) = 8 then value end), max(case when Month(Date) = 7 then value end) from tablename group by title 

Vous pouvez utiliser row_number pour get la dernière date de chaque mois en tant que première ligne de chaque partition.

  select title, max(case when datepart(mm,datecol) = 9 then value end) as sep, max(case when datepart(mm,datecol) = 8 then value end) as aug, max(case when datepart(mm,datecol) = 7 then value end) as jul from ( select *, row_number() over(partition by title,datepart(mm,datecol) order by datecol desc) as rn from t1) t where rn = 1 group by title; 

Fiddle avec des données d'échantillon

Si vous souhaitez faire pivoter les valeurs au cours des trois derniers mois:

 select title, max(case when year(datecol) = year(getdate()) and month(datecol) = month(getdate()) - 2 then value end) as months_2, max(case when year(datecol) = year(getdate()) and month(datecol) = month(getdate()) - 1 then value end) as months_1, max(case when year(datecol) = year(getdate()) and month(datecol) = month(getdate()) then value end) as months_0 from table t group by title; 

MODIFIER:

Oups, je n'ai pas compris la question originale. Voici le code révisé:

 select title, max(case when seqnum = 1 and year(datecol) = year(getdate()) and month(datecol) = month(getdate()) - 2 then value end) as months_2, max(case when seqnum = 1 and year(datecol) = year(getdate()) and month(datecol) = month(getdate()) - 1 then value end) as months_1, max(case when seqnum = 1 and year(datecol) = year(getdate()) and month(datecol) = month(getdate()) then value end) as months_0 from (select t.*, row_number() over (partition by title, year(datecol), month(datecol) order by datecol desc) as seqnum from table t ) t group by title; 

Dans ce cas, le max() ne fait vraiment rien, il suffit de faire pivoter les valeurs.