Commande de paires mois / année dans une requête T-SQL

J'écris une procédure stockée pour afficher le mois et l'année. Cela fonctionne, mais il ne returnne pas les lignes dans l'ordre désiré.

ALTER procedure [dbo].[audioblog_getarchivedates] as begin select DateName(Month,a.createddate) + ' ' + DateName(Year,a.createddate) as ArchiveDate from audio_blog a group by DateName(Month,a.createddate) + ' ' + DateName(Year,a.createddate) order by DateName(Month,a.createddate) + ' ' + DateName(Year,a.createddate) desc end 

Les résultats vont venir comme ceci:

Mars 2010
Janvier 2010
Février 2010

Mais ce n'est pas dans un ordre (desc).

Pas la meilleure solution mais devrait fonctionner jusqu'à ce que vous le découvriez.

 ALTER PROCEDURE [dbo].[Audioblog_getarchivedates] AS BEGIN SELECT DISTINCT Datename(MONTH,a.DATE) + ' ' + Datename(YEAR,a.DATE) AS archivedate, Cast(Datename(MONTH,a.DATE) + ' ' + Datename(YEAR,a.DATE) AS DATETIME) AS tmp FROM audio_blog a ORDER BY tmp DESC END 

Jeff Smith a écrit un excellent article sur les methods de regroupement et de classment par paires Year-Month. J'aime particulièrement son approche d'arrondir la date au premier jour du mois et de la regrouper par cette valeur:

 GROUP BY dateadd(month, datediff(month, 0, SomeDate),0) 

C'est plus rapide car il ne nécessite pas de concaténation de strings.

Vous pouvez convertir cette valeur en une combinaison année-mois plus tard dans la requête en y exécutant YEAR et MONTH pour une représentation conviviale.

Vous voulez order par une valeur datetime, mais vos groupes ne l'ont pas. Une façon est de choisir arbitrairement un des dates créées (par exemple le MAX) dans chaque groupe, et ordewr par ceux-ci:

 select ArchiveDate from ( select DateName(Month,a.createddate) + ' ' + DateName(Year,a.createddate) as ArchiveDate, MAX(createddate) as createddate from (select CONVERT(datetime,createddate) as createddate from (select '20100101' as createddate union all select '20100201' union all select '20100301') t) a group by DateName(Month,a.createddate) + ' ' + DateName(Year,a.createddate) ) g order by g.createddate desc 

Je résous ce type de problème avec une sous-requête. La requête interne a à la fois le DisplyName et SortIndex. La requête externe affiche le nom mais sortinge sur l'index.

par exemple

 select a,b,c DisplayName from (select a, b,c, DisplayName, SortIndex.... ) as Temp order by Temp.SortIndex 

Vous pouvez utiliser cette approche générale avec n'importe quel nombre de champs simplement en ajoutant une paire affichage / index

Terminez avec:

 order by a.createddate desc 

order par 1 (desc)