繁体   English   中英

具有多个选择列的动态数据透视图中的行和列总计

[英]Row and column total in dynamic pivot with multiple Select column

在SQL Server 2008中,我有一个包含4列的表tblStock

PartCode (NVARCHAR (50)) 
Role (NVarchar(10)) 
StockQty (INT) 
Location (NVARCHAR(50))

以下是一些示例数据:

临时表中的数据

我已编写此代码以获取以下输出:

IF OBJECT_ID('tempdb..#tblData') IS NOT NULL 
    DROP TABLE #tblData 

SELECT * 
INTO #tblData 
FROM 
    (SELECT 'A' PartCode, 'Manager' As [Role],  10 StockQty, 'in-A' Location
     UNION ALL
     SELECT 'B', 'Director' As [Role], 22, 'in-A'
     UNION ALL
     SELECT 'A', 'Director' As [Role], 1, 'in-B'
     UNION ALL
     SELECT 'C', 'Director' As [Role], 20, 'in-A'
     UNION ALL
     SELECT 'D', 'Director' As [Role], 39, 'in-F'
     UNION ALL
     SELECT 'E', 'Director' As [Role],  3,   'in-D'
     UNION ALL
     SELECT 'F', 'Director' As [Role],  7,   'in-A'
     UNION ALL
     SELECT 'A', 'Director' As [Role],  9,   'in-C'
     UNION ALL
     SELECT 'D', 'Director' As [Role],  2,   'in-A'
     UNION ALL
     SELECT 'F', 'Director' As [Role],  54,  'in-E') TAB

SELECT * 
FROM #tblData

DECLARE @cols NVARCHAR (MAX)

SELECT @cols = COALESCE (@cols + ',[' + Location + ']', '[' + Location + ']')
               FROM (SELECT DISTINCT Location FROM #tblData) PV 
               ORDER BY Location 

SELECT @cols += ',[Total]' 

DECLARE @NulltoZeroCols NVARCHAR (MAX) 
SELECT @NullToZeroCols = SUBSTRING((SELECT ',ISNULL(['+Location+'],0) AS ['+Location+']' 
FROM (SELECT DISTINCT Location FROM #tblData)TAB  
ORDER BY Location FOR XML PATH('')),2,8000) 

SELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]'

DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT PartCode, Role, ' + @NulltoZeroCols + ' FROM 
             (
                 SELECT 
                 ISNULL(CAST(PartCode AS VARCHAR(30)),''Total'')PartCode, 
                 Role,
                 SUM(StockQty)StockQty , 
                 ISNULL(Location,''Total'')Location              
                 FROM #tblData 
                 GROUP BY Location,PartCode,Role 
                 WITH CUBE
             ) x
             PIVOT 
             (
                 MIN(StockQty)
                 FOR Location IN (' + @cols + ')
            ) p
            ORDER BY CASE WHEN (PartCode=''Total'') THEN 1 ELSE 0 END,PartCode' 

EXEC SP_EXECUTESQL @query 

以上查询的结果是:

错误输出

我想得到这样的结果:

正确的图像

请分享您的想法-谢谢!

不是MIN,请使用SUM。 另外,您不应选择“角色”列。

尝试这个;

DECLARE @cols NVARCHAR (MAX)

SELECT @cols = COALESCE (@cols + ',[' + Location + ']', '[' + Location + ']')
               FROM (SELECT DISTINCT Location FROM #tblData) PV 
               ORDER BY Location 

SELECT @cols += ',[Total]' 

DECLARE @NulltoZeroCols NVARCHAR (MAX) 
SELECT @NullToZeroCols = SUBSTRING((SELECT ',ISNULL(['+Location+'],0) AS ['+Location+']' 
FROM (SELECT DISTINCT Location FROM #tblData)TAB  
ORDER BY Location FOR XML PATH('')),2,8000) 

DECLARE @SumCols NVARCHAR (MAX) 
SELECT @SumCols = SUBSTRING((SELECT '+(ISNULL(['+Location+'],0))' 
FROM (SELECT DISTINCT Location FROM #tblData)TAB  
ORDER BY Location FOR XML PATH('')),2,8000) 
PRINT @SumCols

SET @SumCols += ') AS [Total]'

DECLARE @query NVARCHAR(MAX)
SET @query = 'SELECT PartCode, (SELECT TOP 1 Role FROM #tblData WHERE PartCode=p.PartCode) Role, ' + @NulltoZeroCols +', ('+ @SumCols+' FROM 
             (
                 SELECT 
                 ISNULL(CAST(PartCode AS VARCHAR(30)),''Total'')PartCode, 

                 SUM(StockQty)StockQty , 
                 ISNULL(Location,''Total'')Location              
                 FROM #tblData 
                 GROUP BY Location,PartCode 
                 WITH CUBE
             ) x
             PIVOT 
             (
                 MIN(StockQty)
                 FOR Location IN (' + @cols + ')
            ) p
            ORDER BY CASE WHEN (PartCode=''Total'') THEN 1 ELSE 0 END,PartCode' 
PRINT @query
EXEC SP_EXECUTESQL @query 

更新的部分将是,

SET @query = 'SELECT PartCode, Role, ' + @NulltoZeroCols + ' FROM 
             (
                SELECT PartCode, Role, StockQty, Location
                FROM #tblData
                UNION ALL

                SELECT PartCode, Role, SUM(StockQty), ''Total'' as Location
                FROM #tblData
                GROUP BY PartCode, Role            

                UNION ALL

                  SELECT 
                 ''Total'' PartCode, 
                 ''Total'' Role, 
                 SUM(StockQty)StockQty , 
                 ISNULL(Location,''Total'')Location              
                 FROM #tblData
                 GROUP BY Location   
                 WITH cube
             ) x
             PIVOT 
             (
                 MIN(StockQty)
                 FOR Location IN (' + @cols + ')
            ) p
            ORDER BY CASE WHEN (PartCode=''Total'') THEN 1 ELSE 0 END,PartCode'

DECLARE @query NVARCHAR(MAX) SET @query = 'SELECT p.PartCode, (SELECT TOP 1 Role FROM #tblData t3 WHERE t3.PartCode = p.PartCode and t3.Role = t2.Role ) Role, ' + @NullToZeroCols +', ('+ @SumCols+' FROM ( SELECT ISNULL(CAST(t1.PartCode AS VARCHAR(30)),''Total'')PartCode, -- Role, SUM(StockQty)StockQty , ISNULL(Location,''Total'')Location
FROM #tblData t1 GROUP BY Location,t1.PartCode WITH CUBE ) x PIVOT ( MIN(StockQty) FOR Location IN (' + @cols + ') ) p left JOIN #tblData t2 on t2.PartCode = p.PartCode GROUP BY t2.Role,p.PartCode, ' + @cols +' ORDER BY CASE WHEN (p.PartCode=''Total'') THEN 1 ELSE 0 END,p.PartCode'
SET @query = 'SELECT p.PartCode, (SELECT TOP 1 Role FROM #tblData t3 WHERE t3.PartCode = p.PartCode and t3.Role = t2.Role ) Role, ' + @NullToZeroCols +', ('+ @SumCols+' FROM ( SELECT ISNULL(CAST(t1.PartCode AS VARCHAR(30)),''Total'')PartCode, -- Role, SUM(StockQty)StockQty , ISNULL(Location,''Total'')Location
FROM #tblData t1 GROUP BY Location,t1.PartCode WITH CUBE ) x PIVOT ( MIN(StockQty) FOR Location IN (' + @cols + ') ) p left JOIN #tblData t2 on t2.PartCode = p.PartCode GROUP BY t2.Role,p.PartCode, ' + @cols +' ORDER BY CASE WHEN (p.PartCode=''Total'') THEN 1 ELSE 0 END,p.PartCode'
SET @query = 'SELECT p.PartCode, (SELECT TOP 1 Role FROM #tblData t3 WHERE t3.PartCode = p.PartCode and t3.Role = t2.Role ) Role, ' + @NullToZeroCols +', ('+ @SumCols+' FROM ( SELECT ISNULL(CAST(t1.PartCode AS VARCHAR(30)),''Total'')PartCode, -- Role, SUM(StockQty)StockQty , ISNULL(Location,''Total'')Location
FROM #tblData t1 GROUP BY Location,t1.PartCode WITH CUBE ) x PIVOT ( MIN(StockQty) FOR Location IN (' + @cols + ') ) p left JOIN #tblData t2 on t2.PartCode = p.PartCode GROUP BY t2.Role,p.PartCode, ' + @cols +' ORDER BY CASE WHEN (p.PartCode=''Total'') THEN 1 ELSE 0 END,p.PartCode'
PRINT @query EXEC (@query)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM