5

我遇到了一个我无法解决的问题,并且已经尝试了所有方法。希望我能在这里得到答案。

我表中的数据如下

Id Month Val1 Val2 Val3
1  Jan   70   80   90
2  Jan   12   13   15
3  Feb   12   67   99
4  March 14   15   17.1

从以下结构中,我想基于列旋转数据,val1因此我的输出将如下所示:

Jan Jan Feb March
70  12  12  14
4

2 回答 2

3

您将需要使用我认为的动态 SQL(除非您的列将保持静态)

需要执行的查询是:

SELECT  [Jan] = [Jan1], 
        [Jan] = [Jan2], 
        [Feb] = [Feb1], 
        [March] = [March1]
FROM    (   SELECT  [PivotColumn] = [Month] + CONVERT(VARCHAR(10), ROW_NUMBER() OVER(PARTITION BY [Month] ORDER BY ID)), 
                    Val1
            FROM    T
        ) t
        PIVOT
        (   MAX(Val1)
            FOR [PivotColumn] IN ([Jan1], [Jan2], [Feb1], [March1])
        ) pvt

虽然我不确定为什么会这样

Jan Jan Feb March
70  12  12  14

并不是

Jan Jan Feb March
12  70  12  14

所以你可能需要修改函数ORDER BY中的ROW_NUMBER

要动态构建它,您可以使用:

-- CREATE SAMPLE TABLE AND INSERT DATA
CREATE TABLE #T (ID INT, Month VARCHAR(10), Val1 INT, Val2 INT, Val3 DECIMAL(5, 1));
INSERT #T VALUES (1, 'Jan', 70, 80, 90), (2, 'Jan', 12, 13, 15), (3, 'Feb', 12, 67, 99), (4, 'March', 14, 15, 17.1);

-- DECLARE VARIABLES TO STORE THE COLUMN NAMES
DECLARE @PivotList NVARCHAR(MAX) = '',
        @ColumnList NVARCHAR(MAX) = '';

-- HERE USE ROW_NUMBER() TO UNIQUELY IDENTIFY VALUES FOR MONTHS 
-- THIS MEANS JAN: 70 AND JAN: 12 CAN BE IDENTIFIED SEPARATELY LATER, BUT RETAIN THE DUPLICATE COLUMN NAME [Jan]
SELECT  @ColumnList = @ColumnList + ', ' + QUOTENAME([Month]) + ' = ' + QUOTENAME([Month] + CONVERT(VARCHAR(10), ROW_NUMBER() OVER(PARTITION BY [Month] ORDER BY ID))),
        @PivotList = @PivotList + ', ' + QUOTENAME([Month] + CONVERT(VARCHAR(10), ROW_NUMBER() OVER(PARTITION BY [Month] ORDER BY ID)))
FROM    #T
ORDER BY ID;

DECLARE @SQL NVARCHAR(MAX) = 'SELECT ' + STUFF(@ColumnList, 1, 2, '') + '
                            FROM    (   SELECT  [PivotColumn] = [Month] + CONVERT(VARCHAR(10), ROW_NUMBER() OVER(PARTITION BY [Month] ORDER BY ID)), 
                                                Val1
                                        FROM    #T
                                    ) t
                                    PIVOT
                                    (   MAX(Val1)
                                        FOR [PivotColumn] IN (' + STUFF(@PivotList, 1, 2, '') + ')
                                    ) pvt';

EXECUTE SP_EXECUTESQL @SQL;

DROP TABLE #T;

同样,will 中的任何更改ROW_NUMBER也需要反映在ORDER BY生成列名称和数据透视表的查询中的子句中:

SELECT  @ColumnList = @ColumnList + ', ' + QUOTENAME([Month]) + ' = ' + QUOTENAME([Month] + CONVERT(VARCHAR(10), ROW_NUMBER() OVER(PARTITION BY [Month] ORDER BY ID))),
        @PivotList = @PivotList + ', ' + QUOTENAME([Month] + CONVERT(VARCHAR(10), ROW_NUMBER() OVER(PARTITION BY [Month] ORDER BY ID)))
FROM    #T
ORDER BY ID;
于 2012-10-22T12:43:47.807 回答
0

这对我有用:

SELECT * FROM
(select COUNT(isnull(intFileStatus,0)) as FileCount , case cast(intfilestatus as nvarchar(25)) when '0' then 'Not Allocated'  when '1' then 'Assigned' when '2' then 'Pending' when '3'  then 'Send For Qc'  when '4' then 'Allocated To Qc' when '5' then 'Finish Qc'  when '7' then 'Delivered'  else cast(isnull(intFileStatus,0) as nvarchar (25)) end FileStatusfrom dbo.tblLPO_FileDetails   group by intFileStatus ) AS original
PIVOT 
(
    MIN(FileCount) FOR [FileStatus] IN ([Not Allocated], [Assigned], [Pending],[Send For Qc],[Allocated To Qc],[Finish Qc],[Delivered])
) AS PivotTable

试一试..

于 2013-01-05T12:09:05.227 回答