我有这个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))
结果
但我想要下面的结果
我使用GROUP BY GROUPING SETS
,GROUP BY ROLLUP
,GROUP BY CUBE
但没有运气。
如果我删除GROUP BY和GROUPING SETS等,简单数据将如下所示
Excel文件Google云端硬盘链接:https://drive.google.com/open?id=1DgyI_7-p1l7n1KjeAnf1DerQTGLJC-wB
Excel文件有3张
答案 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;