如何获得子总数和总计基于Sql Server中的标题和子标题

时间:2018-03-04 12:38:43

标签: sql sql-server sql-server-2008 group-by grouping

我有这个SQL代码

SELECT TOP (100) PERCENT 
    dbo._SHIFT._SHIFTNAME AS [Shift Name], dbo._TANK._TANKNAME AS [Tank Name],
    dbo._NOZZLE._NOZZLENAME AS [Nozzle Name], 
    dbo._SHIFTENTRYDET._OPENING AS Opening, dbo._SHIFTENTRYDET._CLOSING AS Closing, 
    SUM(dbo._SHIFTENTRYDET._TOTALSALE) AS [Total Sale], 
    dbo._SHIFTENTRYDET._RATE AS Rate, 
    CASE
       WHEN GROUPING(dbo._SHIFT._SHIFTNAME) = 1 
          THEN NULL 
       WHEN GROUPING(dbo._TANK._TANKNAME) = 1 
          THEN NULL
       ELSE SUM(dbo._SHIFTENTRYDET._TOTALAMOUNT)
    END AS Amount
FROM      
    dbo._NOZZLE 
RIGHT OUTER JOIN
    dbo._SHIFTENTRYDET ON dbo._NOZZLE._NOZZLEID_PK = dbo._SHIFTENTRYDET._NOZZLEID_PK 
LEFT OUTER JOIN
    dbo._TANK ON dbo._SHIFTENTRYDET._TANKID_PK = dbo._TANK._TANKID_PK 
RIGHT OUTER JOIN
    dbo._SHIFTENTRY ON dbo._SHIFTENTRYDET._SHIFTENTRYID_PK = dbo._SHIFTENTRY._SHIFTENTRYID_PK 
LEFT OUTER JOIN
    dbo._SHIFT ON dbo._SHIFTENTRY._SHIFTID_PK = dbo._SHIFT._SHIFTID_PK
WHERE     
    (dbo._SHIFTENTRY._ISDELETED = N'1') 
    AND (dbo._SHIFT._ISDELETED = N'1') 
    AND (dbo._SHIFTENTRYDET._ISDELETED = N'1')
GROUP BY GROUPING SETS  
    ((dbo._SHIFT._SHIFTNAME, dbo._TANK._TANKNAME, dbo._NOZZLE._NOZZLENAME, dbo._SHIFTENTRYDET._OPENING, dbo._SHIFTENTRYDET._CLOSING, dbo._SHIFTENTRYDET._RATE), (dbo._SHIFT._SHIFTNAME, dbo._TANK._TANKNAME)) 

结果

enter image description here

但我想要下面的结果

enter image description here enter image description here

我使用GROUP BY GROUPING SETSGROUP BY ROLLUPGROUP BY CUBE但没有运气。

如果我删除GROUP BY和GROUPING SETS等,简单数据将如下所示

enter image description here

Excel文件Google云端硬盘链接:https://drive.google.com/open?id=1DgyI_7-p1l7n1KjeAnf1DerQTGLJC-wB

Excel文件有3张

  1. 示例数据,此处没有groupiung的数据
  2. 预期结果
  3. 结果使用GROUPING SETS

1 个答案:

答案 0 :(得分:1)

您的两个分组集都包含Shiftname和Tankname,因此分组功能将始终返回0.

由于WHERE子句包含Shift,Shiftentry和Shiftentrydet的条件,因此记录必须存在,因此连接是INNER JOIN(好的,也许不适用于Tank和Nozzle)。

按键值而不是显示名称进行分组会更好一点,而且按照其他信息进行分组(打开,关闭...)在我看来似乎是错误的。应该分组的唯一字段是Shift,Tank和Shiftentrydet的键(而不是Nozzle,因为Nozzle似乎构成细节),所以我将在子查询(CTE)中进行分组和计算并加入其余的在主查询中,虽然查询Shiftentrydet和Shift表两次(一次用于计算,一次用于显示)。我想Shiftentrydet_PK列确实存在。)

最后,您的查询不会返回同一列中总计的Shift-Tank-和Nozzle-名称和标题,也不会为Shift和Tank创建标题行。为实现这一目标,我建议使用报告(SSRS)。

对于仅查询的非报告解决方案,请尝试此操作(未测试):

WITH CTE_grp (SHIFTID_PK, TANKID_PK, Shipentrydet_PK, Amount) AS (
    SELECT se._SHIFTID_PK, sed._TANKID_PK, sed.Shipentrydet_PK, SUM(sed._TOTALAMOUNT)
    FROM dbo._SHIFT s
      INNER JOIN dbo._SHIFTENTRY se ON s._SHIFTID_PK = se._SHIFTID_PK
      INNER JOIN dbo._SHIFTENTRYDET sed ON se._SHIFTENTRYID_PK = sed._SHIFTENTRYID_PK
    WHERE (se._ISDELETED = N'1') AND (sed._ISDELETED = N'1') AND (s._ISDELETED = N'1')
    GROUP BY se._SHIFTID_PK, sed._TANKID_PK, sed.Shipentrydet_PK WITH ROLLUP
)
SELECT s._SHIFTNAME AS [Shift Name], t._TANKNAME AS [Tank Name], n._NOZZLENAME AS [Nozzle Name]
  , sed._OPENING AS Opening, sed._CLOSING AS Closing, sed._TOTALSALE AS [Total Sale]
  , sed._RATE AS Rate, c.Amount
FROM CTE_grp c
  LEFT OUTER JOIN dbo._SHIFT s ON c.SHIFTID_PK = s._SHIFTID_PK
  LEFT OUTER JOIN dbo._TANK t ON c.TANKID_PK = t._TANKID_PK
  LEFT OUTER JOIN  dbo._SHIFTENTRYDET sed ON c.Shipentrydet_PK = sed.Shipentrydet_PK
    LEFT OUTER JOIN dbo._NOZZLE n ON sed._NOZZLEID_PK = n._NOZZLEID_PK;