当你想将三个字段合并为一个类别时如何使用数据透视表

How to use pivot when you want to combine three field in one category

我有这种格式的数据

Skill   Min  Ideal  Max
==========================
 C++    0      1    1

我要这样显示

Criteria    C++

=================

 Min          0
 Ideal        1
 Max          1

我对将 Min 、 Ideal 和 Max 转换为标准的部分感到困惑。

--Check for TempTable existence, drop if exists

IF OBJECT_ID('tempdb..#Stack') IS NOT NULL
BEGIN
    DROP TABLE #Stack;
END
GO

--Create Table

CREATE TABLE #Stack
([Skill] VARCHAR(10)
 , [Min] INT
 , [Ideal] INT
 , [Max] INT);

--Insert Sample data

 INSERT INTO #Stack([Skill], [Min], [Ideal], [Max])
 SELECT 'C++', 0, 1, 1;

--Check inserted data

SELECT [Skill], [Min], [Ideal], [Max] FROM #Stack;

++++++++++++++++++++++++++++
Skill   Min     Ideal   Max
++++++++++++++++++++++++++++
C++     0       1       1 
++++++++++++++++++++++++++++

--Use Unpivot to get desired result

SELECT u.Criteria, u.[C++]
FROM #Stack
UNPIVOT
(
    [C++] FOR [Criteria] IN ([Min], [Ideal], [Max])
) u;

++++++++++++++++++
Criteria    C++
++++++++++++++++++
Min         0
Ideal       1
Max         1
++++++++++++++++++

但是,如果再增加1个技能呢?

 INSERT INTO #Stack([Skill], [Min], [Ideal], [Max])
 SELECT 'C#', 1, 1, 1;

我们的数据现在

++++++++++++++++++++++++++++
Skill   Min     Ideal   Max
++++++++++++++++++++++++++++
C++     0       1       1
C#      1       1       1   
++++++++++++++++++++++++++++

和上面相同的 Unpivot 查询,给我们以下结果

++++++++++++++++++
Criteria    C++
++++++++++++++++++
Min         0
Ideal       1
Max         1
Min         1
Ideal       1
Max         1
++++++++++++++++++

所以为了解决这个问题,我使用了一些动态 sql,如下所示:

DECLARE @cols AS NVARCHAR(MAX);
DECLARE @pivcols AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);

--Get dynamic list of Skill
SELECT @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(Skill)
                      FROM #Stack
                      FOR XML PATH(''), TYPE
                     ).value('.', 'NVARCHAR(MAX)') 
                        , 1, 1, '');

--Build dynamic list of columns pre-pend with alias piv.
SELECT @pivcols = STUFF((SELECT DISTINCT ',piv.' + QUOTENAME(Skill)
                         FROM #Stack
                         FOR XML PATH(''), TYPE
                        ).value('.', 'NVARCHAR(MAX)') 
                           , 1, 1, '');

--Build query for Unpivot and Pivot
SELECT @query = '
SELECT piv.Criteria, ' + @pivcols + '
FROM
(
    SELECT Skill, [Min], Ideal, [Max]
    FROM #Stack
) d
UNPIVOT
(
    [value] FOR [Criteria] IN ([Min],[Ideal],[Max])
) AS unpiv
PIVOT
(
    MAX([value]) 
    FOR [Skill] IN (' + @cols + ')
) AS piv'

EXECUTE(@query);

这现在应该给我们以下结果

+++++++++++++++++++++++
Criteria    C#  C++
+++++++++++++++++++++++
Ideal       1   1
Max         1   1
Min         1   0
+++++++++++++++++++++++

您可以阅读有关此方法和另一种方法的更多信息 Cross Apply from the dba.StackExchange answer here by user Julien Vavasseur

我也参考了Books Online PIVOT/UNPIVOT usage