使用 Case 语句的动态数据透视表。另一个角度

Dynamic Pivot Using Case Statement. Another angle

我在这里创建了这个 table 并在下面插入了值

CREATE TABLE temp1
(
ProcessName varchar(50),
ProcessNo varchar(50),
ProcessPages varchar(50)    
)

INSERT INTO temp1 VALUES ('PRO1','PR012','5');
INSERT INTO temp1 VALUES ('PRO1','PR012','4');
INSERT INTO temp1 VALUES ('PRO1','PR012','10');
INSERT INTO temp1 VALUES ('PRO1','PR012','7');
INSERT INTO temp1 VALUES ('PRO1','PR012','6');
INSERT INTO temp1 VALUES ('PRO1','PR012','14');
INSERT INTO temp1 VALUES ('PRO1','PR012','23');
INSERT INTO temp1 VALUES ('PRO1','PR012','45');
INSERT INTO temp1 VALUES ('PRO1','PR012','52');
INSERT INTO temp1 VALUES ('PRO2','PR022','3');
INSERT INTO temp1 VALUES ('PRO2','PR022','5');
INSERT INTO temp1 VALUES ('PRO2','PR022','6');
INSERT INTO temp1 VALUES ('PRO2','PR022','5');
INSERT INTO temp1 VALUES ('PRO2','PR022','5');
INSERT INTO temp1 VALUES ('PRO2','PR022','8');
INSERT INTO temp1 VALUES ('PRO2','PR022','5');
INSERT INTO temp1 VALUES ('PRO2','PR022','2');
INSERT INTO temp1 VALUES ('PRO2','PR022','3');
INSERT INTO temp1 VALUES ('PRO2','PR022','3');
INSERT INTO temp1 VALUES ('PRO3','PR032','5');
INSERT INTO temp1 VALUES ('PRO3','PR032','10');
INSERT INTO temp1 VALUES ('PRO3','PR032','15');
INSERT INTO temp1 VALUES ('PRO3','PR032','25');
INSERT INTO temp1 VALUES ('PRO3','PR032','35');
INSERT INTO temp1 VALUES ('PRO3','PR032','45');
INSERT INTO temp1 VALUES ('PRO3','PR032','55');
INSERT INTO temp1 VALUES ('PRO3','PR032','25');
INSERT INTO temp1 VALUES ('PRO3','PR032','25');
INSERT INTO temp1 VALUES ('PRO3','PR032','20');
INSERT INTO temp1 VALUES ('PRO3','PR032','3');
INSERT INTO temp1 VALUES ('PRO3','PR032','3');

我正在尝试编写一个动态枢轴来实现这个

Process_No_In_Cases PR01    PR02    PR03
1p                  2       8       3
2p                  3       2       1
3p                  1       0       1
4p                  2       0       1
5p                  1       0       6
Total               9       10      12

使用下面的代码:

DECLARE @ColumnNames NVARCHAR(MAX)
DECLARE @SQL NVARCHAR(MAX)

SELECT @ColumnNames=Stuff((SELECT DISTINCT ',' + Quotename(ProcessName)
                   FROM temp1
                   FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
SET @SQL=
'SELECT * FROM

    ( SELECT
       ProcessPages  
       ,ProcessName
      ,ProcessNo 
      FROM temp1 AS BaseData
PIVOT(

     COUNT(ProcessNo)
     FOR ProcessName
     IN('+@ColumnNames +
           ')


) As PivotTable'
--print @sql


EXECUTE sp_executesql @SQL

如何将下面的代码与上面的代码合并以实现下面的数据(我在 post 的顶部提供了相同的数据):

SELECT * 

FROM
 (SELECT [ProcessName], 
        COUNT(CASE WHEN ProcessPages >=1 and ProcessPages<=5  THEN '1p' END) AS [1p],
        COUNT(CASE WHEN ProcessPages >=6 and ProcessPages<=10 THEN '2p' END) AS [2p],
        COUNT(CASE WHEN ProcessPages >=11 and ProcessPages<=16  THEN '3p' END) AS [3p],
        COUNT(CASE WHEN ProcessPages >=17 and ProcessPages<=50 THEN '4p' END) AS [4p],
        COUNT(CASE WHEN  ProcessPages>50 THEN '5p' END) AS [5p],
        COUNT([ProcessName]) AS Total
   FROM temp1
  GROUP BY [ProcessName]) AS SOURCE

期望的输出:

Process_No_In_Cases PR01    PR02    PR03
1p                  2       8       3
2p                  3       2       1
3p                  1       0       1
4p                  2       0       1
5p                  1       0       6
Total               9       10      12

我认为下面的查询可能是您想要的。有可能它可以改进,因为它先做一个逆轴,然后再做一个轴,但无论如何它应该给你一些想法。

DECLARE @ColumnNames NVARCHAR(MAX)
DECLARE @SQL NVARCHAR(MAX)

SELECT @ColumnNames=Stuff((SELECT DISTINCT ',' + Quotename(ProcessName)
                   FROM [temp1]
                   FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
SET @SQL= '
SELECT * FROM (
    SELECT [ProcessName], 
        COUNT(CASE WHEN ProcessPages >=  1 and ProcessPages <=  5 THEN ''1p'' END) AS [1p],
        COUNT(CASE WHEN ProcessPages >=  6 and ProcessPages <= 10 THEN ''2p'' END) AS [2p],
        COUNT(CASE WHEN ProcessPages >= 11 and ProcessPages <= 16 THEN ''3p'' END) AS [3p],
        COUNT(CASE WHEN ProcessPages >= 17 and ProcessPages <= 50 THEN ''4p'' END) AS [4p],
        COUNT(CASE WHEN ProcessPages >  50                        THEN ''5p'' END) AS [5p],
        COUNT([ProcessName]) AS Total
    FROM temp1
    GROUP BY [ProcessName]) AS SOURCE
    UNPIVOT ( val FOR Process_No_In_Cases IN ([1p],[2p],[3p],[4p],[5p],[Total]) ) U
      PIVOT ( MAX(val) FOR ProcessName IN ('+@ColumnNames +') ) As PivotTable'
EXECUTE sp_executesql @SQL