如何使用每行的总计列来旋转查询结果

时间:2016-11-30 06:53:31

标签: sql-server tsql pivot pivot-table

DECLARE @TimeByDay VARCHAR(max)

SET @TimeByDay = LTRIM(RTRIM(
  (
    SELECT QUOTENAME(REPLACE(LEFT(DATENAME(dw, TimeByDay), 3) + ', ' + CAST(TimeByDay AS varchar(11)),'''',''''''),'[') + ', '           
    FROM #TimesheetLineData
    GROUP BY TimeByDay
    ORDER BY TimeByDay
    FOR XML PATH('')
  )))
  SET @TimeByDay = LEFT(@TimeByDay, Len(@TimeByDay) - 1)
  --PRINT 'columns -' + @TimeByDay;

DECLARE @sql VARCHAR(MAX), @sql2 VARCHAR(MAX), @sql3 VARCHAR(MAX), @sql4 VARCHAR(MAX),@sql5 Varchar(Max),@sql6 Varchar(Max),@sql7 Varchar(Max),@sql8 Varchar(Max);

SET @sql = 'SELECT *,0 As OrderID 
        INTO ##fp_FetchTimeSheet_PWA_Data 
        FROM 
        ('

SET @sql3 = ' 
        SELECT ResourceName AS ResourceName
            , SOW
            , TaskName As [Task Name/Description]
            , ' + @TimeByDay + '

    FROM
    (
        SELECT 
        ResourceName,
        SOW,    
        TaskName,
        LEFT(DATENAME(dw, TimeByDay), 3) + '', '' + CAST(TimeByDay AS varchar(11)) AS TimeByDay,
        CAST(CAST(ActualWorkBillable as decimal(8,1)) as Varchar)+ '' h''  AS PlannedWork
        FROM #TimesheetLineData'

SET @sql3=@sql3 + ') AS SourceTable
    PIVOT
    (
        MAX(PlannedWork)'
SET @sql4 = ' FOR TimeByDay IN ('+ @TimeByDay +')
    ) AS PivotTable
    ) A 
    ORDER BY ResourceName, [Task Name/Description],SOW';

EXEC  (@sql + @sql3 + @sql4)

SET @sql5 = 'INSERT INTO ##fp_FetchTimeSheet_PWA_Data 
    SELECT *,1 As OrderID FROM
        ('

SET @sql7 = ' 
        SELECT ResourceName
            , NULL As SOW               
            , ''Total Actual Work'' As [Task Name/Description]
            , ' + @TimeByDay + '
    FROM
    (
        SELECT 
            ResourceName, 
            SOW,
            [Task Name/Description],
            LEFT(DATENAME(dw, TimeByDay), 3) + '', '' + CAST(TimeByDay AS varchar(11)) AS TimeByDay,
            TotalActualWork
        from #TimesheetLineDataSummary'

set @sql7=@sql7 + ') AS SourceTable
    PIVOT
    (
        MAX(TotalActualWork)'

SET @sql8 = ' FOR TimeByDay IN ('+ @TimeByDay +')
    ) AS PivotTable
    )A
    ORDER BY ResourceName, [Task Name/Description]';

exec  (@sql5 + @sql7 + @sql8)

SELECT *
FROM ##fp_FetchTimeSheet_PWA_Data
ORDER BY ResourceName,OrderID

我有上面的查询,它使用带动态列的pivot作为存储过程的一部分。到目前为止,查询工作正常但我正在努力为每个返回的行添加一个授权总计列,这将是动态生成的列的总和(在变量@TimeByDay中)

我正在尝试关注这里的一篇文章https://www.codeproject.com/articles/232181/sql-pivot-with-grand-total-column-and-row但是有些怎样,我似乎无法让它发挥作用。

1 个答案:

答案 0 :(得分:2)

一般情况下:总计是 - 在大多数情况下! - 表示层应该计算的东西。

如果必须这样做,您有两种选择:

  1. 让您的SP按原样返回SELECT 并再放一个SELECT,它只返回一行,包含您需要的所有SUM。根据您调用此工具的工具,只需一次调用SP即可读取多个结果集。

  2. 使用类似这样的内容

  3. 代码使用UNION ALL来添加总计。需要RowInx和排序以确保正确的顺序和最后一个位置的总计

    DECLARE @tbl TABLE (ID INT IDENTITY,val1 INT, val2 INT);
    INSERT INTO @tbl VALUES (1,2),(3,4),(5,6);
    
    SELECT ID,val1,val2
    FROM
    (
        SELECT ROW_NUMBER() OVER(ORDER BY ID) AS RowInx, * FROM @tbl
        UNION ALL
        SELECT 1000000,NULL,SUM(val1),SUM(val2) FROM @tbl
    ) AS t
    ORDER BY t.RowInx