Sorting month name in dynamic pivot

一个人想着一个人 提交于 2019-12-05 12:21:49

I'd use the following approach to sort the months in ascending order

Demo

SELECT 
            Num,
            [Types],
            StartDate,
            FORMAT(StartDate,'MMM-yy')AS MonthYear,
            CONVERT(INT,REPLACE(CONVERT(VARCHAR(7),StartDate),'-','')) MonthYearSort
    INTO ##MyTable2
    FROM ##MyTable

DECLARE @cols AS NVARCHAR(MAX)='',
        @query  AS NVARCHAR(MAX);


WITH T AS
(
SELECT TOP 100 PERCENT QUOTENAME(MonthYear) MonthYear  , MonthYearSort
FROM ##MyTable2
GROUP BY QUOTENAME(MonthYear)  , MonthYearSort
ORDER BY MonthYearSort
)

SELECT @cols += ','+ MonthYear 
FROM T
ORDER BY MonthYearSort
SET @cols = STUFF(@Cols ,1,1,'')


set @query = ' SELECT [Types], '+@cols+' FROM (
                SELECT
                Num,
                [Types],
                MonthYear
                FROM ##MyTable2) AS PV
PIVOT
(
COUNT(Num) FOR [MonthYear] IN (' + @cols + ')
) AS PV1

EXECUTE (@query);

You can change the @cols query to:

SET @cols = STUFF((SELECT ',' + MAX(QUOTENAME(MonthYear))
            FROM ##MyTable2 c
            GROUP BY MONTH(StartDate), YEAR(StartDate) -- use group by instead of distinct
            ORDER BY YEAR(StartDate), MONTH(StartDate) -- use `order by` here    
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

This produces:

[Jan-16],[Feb-16],[Aug-16],[Sep-16],[Jan-17],[Feb-17],[Oct-17],[Jan-18]

Demo here

Edit: (thanks to @EzequielLópezPetrucci)

You should also use 'Types, ' + @cols instead of * in order to explicitly specify the column order. * doesn't guarantee that the ordinal position of each column returned by the SELECT will be the same as the position defined on table creation.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!