如何在动态pivot sql中总计超过1

时间:2017-09-12 06:46:57

标签: sql sql-server pivot

我正在尝试使用动态数据透视图中的2 coulin创建一个总计和2个子总计的查询。

我有桌子和桌子像这样查询

enter image description here

CREATE TABLE #SampleData
(
    Class varchar(10),
    Name varchar(10),
    Location varchar(10),
    Item varchar(10),
    temp varchar (10)
)

INSERT INTO #SampleData
VALUES
('abc', 'Ron', 'A', 'Pencil', '12345'),
('abc', 'Ron', 'A', 'Pen', '2345'),
('abc', 'Tom', 'C', 'Pencil', '34343'),
('abc', 'Tom', 'D', 'Pencil', '252525'),
('def', 'Ron', 'E', 'Pen', '35345'),
('def', 'Tom', 'F', 'Pencil', '87878'),
('def', 'Tom', 'G', 'Pen', '9876'),
('ghi', 'Ron', 'H', 'Pen', '09090'),
('ghi', 'Ron', 'I', 'Pen', '40404'),
('ghi', 'Tom', 'J', 'Pencil', '144442345'),
('ghi', 'Tom', 'K', 'Pencil', '4444333')


DECLARE @Pivot_Columns  AS VARCHAR(MAX),
        @select_Columns VARCHAR(max)

SELECT @Pivot_Columns = Stuff((SELECT DISTINCT ',' + Quotename(item) FROM #SampleData FOR xml path('')), 1, 1, '')
SELECT @select_Columns = Stuff((SELECT DISTINCT ',Sum(' + Quotename(item) + ') as '+Quotename(item) FROM #SampleData FOR xml path('')), 1, 1, '')

DECLARE @SQL AS VARCHAR(MAX)

SET @SQL = 'SELECT case when grouping(name) = 1 and grouping(class) = 0 then ''Total''+ '' '' + class 
when grouping(name) = 1 and grouping(class) = 1 then ''Total'' 
else class end class, name, location, temp,'
           + @select_Columns + '
FROM
(
    SELECT class, name, location, item, temp
    FROM #SampleData

) as PivotData
PIVOT
(
    count(item)
    for item  IN ('
           + @Pivot_Columns + ')
) AS PivotResult
group by class, name, location, temp with rollup 
'

EXEC(@SQL)

如何创建这样的数据? enter image description here

我只想根据课程和时间显示姓名小计。小计类,但在我的第一个成像器中有基于temp的子总数。如果我按类更改“按汇总命名”,则会显示错误..

感谢任何帮助,谢谢你。

2 个答案:

答案 0 :(得分:1)

我想你可以尝试一下(我刚刚审查了第一个案例,为名称添加了CASE并添加了HAVING条件):

SET @SQL = 'SELECT 
                    case when grouping(name) = 1 and grouping(class) = 0 then ''TOTAL ''+ '' '' + class  
                        when grouping(name) = 1 and grouping(class) = 1 then ''TOTAL ''                     
                        else class end class
            ,  case when grouping(location)=1 AND grouping(temp)=1 THEN ''TOTAL ''+name
                        else name end name, location, temp,'
           + @select_Columns + '
FROM
(
    SELECT class, name, location, item, temp
    FROM #SampleData

) as PivotData
PIVOT
(
    count(item)
    for item  IN ('
           + @Pivot_Columns + ')
) AS PivotResult
group by class, name, location, temp with ROLLUP 
HAVING (grouping(location)=1 AND grouping(temp)=1 ) OR (grouping(location)=0 AND grouping(temp)=0 AND grouping(name)=0 AND grouping(class)=0)
'

<强>更新

您可以使用GROUPING SETS,获得相同的结果(避免在我之前的查询中使用HAVING条件):

SET @SQL = 'SELECT 
                    case when grouping(name) = 1 and grouping(class) = 0 then ''TOTAL ''+ '' '' + class  
                        when grouping(name) = 1 and grouping(class) = 1 then ''TOTAL ''                     
                        else class end class
            ,  case when grouping(location)=1 AND grouping(temp)=1 THEN ''TOTAL ''+name
                        else name end name, location, temp,'
           + @select_Columns + '
FROM
(
    SELECT class, name, location, item, temp
    FROM #SampleData

) as PivotData
PIVOT
(
    count(item)
    for item  IN ('
           + @Pivot_Columns + ')
) AS PivotResult
group by GROUPING SETS ((class,name), (class), (class, name, location, temp),())

'

输出:

+------------+-----------+----------+-----------+-----+--------+
|   class    |   name    | location |   temp    | Pen | Pencil |
+------------+-----------+----------+-----------+-----+--------+
| abc        | Ron       | A        | 12345     |   0 |      1 |
| abc        | Ron       | A        | 2345      |   1 |      0 |
| abc        | TOTAL Ron | NULL     | NULL      |   1 |      1 |
| abc        | Tom       | C        | 34343     |   0 |      1 |
| abc        | Tom       | D        | 252525    |   0 |      1 |
| abc        | TOTAL Tom | NULL     | NULL      |   0 |      2 |
| TOTAL  abc | NULL      | NULL     | NULL      |   1 |      3 |
| def        | Ron       | E        | 35345     |   1 |      0 |
| def        | TOTAL Ron | NULL     | NULL      |   1 |      0 |
| def        | Tom       | F        | 87878     |   0 |      1 |
| def        | Tom       | G        | 9876      |   1 |      0 |
| def        | TOTAL Tom | NULL     | NULL      |   1 |      1 |
| TOTAL  def | NULL      | NULL     | NULL      |   2 |      1 |
| ghi        | Ron       | H        | 09090     |   1 |      0 |
| ghi        | Ron       | I        | 40404     |   1 |      0 |
| ghi        | TOTAL Ron | NULL     | NULL      |   2 |      0 |
| ghi        | Tom       | J        | 144442345 |   0 |      1 |
| ghi        | Tom       | K        | 4444333   |   0 |      1 |
| ghi        | TOTAL Tom | NULL     | NULL      |   0 |      2 |
| TOTAL  ghi | NULL      | NULL     | NULL      |   2 |      2 |
| TOTAL      | NULL      | NULL     | NULL      |   5 |      6 |
+------------+-----------+----------+-----------+-----+--------+

答案 1 :(得分:0)

您可能会发现 this link 很有帮助。

或者,这是另一种解决方案:

SELECT SUM(CASE WHEN Code = '01' THEN Value1 ELSE 0 END) AS Value1_01  
    ,SUM(CASE WHEN Code = '02' THEN Value1 ELSE 0 END) AS Value1_02  
    ,SUM(CASE WHEN Code = '01' THEN Value2  ELSE 0 END) AS Value2_01  
    ,SUM(CASE WHEN Code = '02' THEN Value2  ELSE 0 END) AS Value2_02  
FROM TableName