我正在使用SQL Server 2008 R2和T-SQL。这些是缩写的例子。
我的表/视图包含以下字段
Table/View
ReportID,
UnitName,
UnitID,
CaseDefinitionID,
CaseDefinition,
DateOfDelivery,
YEAR(DateOfDelivery) AS [Year],
MONTH(DateOfDelivery) AS [Month],
DATENAME(m,DateOfDelivery) AS [Month name]
我的目标报告是:
Unit | Case type 1| Case type 2| Case total|
Unit A | 36| 40| 76|
2013| 20| 18| 38|
Jan| 10|
Feb| 10|
2014| 16|
Mar| 8|
Dec| 8|
Unit B | 12|
2013| 12|
Jan| 6|
May| 6|
Grand total| 48|
月份行可以为空,NULL内容也可以。示例报告不完整以帮助澄清。
到目前为止的进展是以下查询:
SELECT *
FROM
(
SELECT
PCT.[Year],
PCT.UnitName AS [Unit],
PCT.UnitID,
PCT.CaseDefinition AS [Case definition]
FROM
PivotBase AS PCT
) AS P1
PIVOT
(
COUNT(UnitID)
FOR [Case definition] IN ([Case type 1],[Case type 2])
) AS P2
这将产生下表
Year|Unit |Case type 1|Case type 2|
2013|Unit A | 20 | 18|
2014|Unit A | 16 | 22|
2013|Unit B | 6 | 8|
2014|Unit B | 6 | 8|
不需要动态SQL
到目前为止,我的阅读内容涵盖了许多选项,但我仍然不知道下一步该怎么做。如何生成所需的报告。
答案 0 :(得分:2)
可以使用一些花哨的汇总(SQL Fiddle)
;WITH
CTE1 AS
(
SELECT UnitName,
[Year],
[Month],
CaseDefinition,
GROUPING_ID(UnitName,[Year],[Month],CaseDefinition)
AS GroupingID,
CASE GROUPING_ID(CaseDefinition,UnitName,[Year],[Month])
WHEN 0 THEN UnitName + '-' + CAST(Year AS varchar(4)) + '-' + RIGHT('0' + CAST([Month] AS varchar(10)),2)
WHEN 1 THEN UnitName + '-' + CAST(Year AS varchar(4))
WHEN 3 THEN UnitName
WHEN 7 THEN 'zzz' -- So that grand total appears at the bottom
ELSE NULL
END AS GroupingLevel,
CASE GROUPING_ID(CaseDefinition,UnitName,[Year],[Month])
WHEN 0 THEN ' ' + CASE [Month]
WHEN 1 THEN 'Jan'
WHEN 2 THEN 'Feb'
WHEN 3 THEN 'Mar'
WHEN 4 THEN 'Apr'
WHEN 5 THEN 'May'
WHEN 6 THEN 'Jun'
WHEN 7 THEN 'Jul'
WHEN 8 THEN 'Aug'
WHEN 9 THEN 'Sep'
WHEN 10 THEN 'Oct'
WHEN 11 THEN 'Nov'
WHEN 12 THEN 'Dec'
END
WHEN 1 THEN ' ' + CAST([Year] AS varchar(4))
WHEN 3 THEN UnitName
WHEN 7 THEN 'Grand Total'
END AS DisplayName,
COUNT(UnitID) AS UnitCount
FROM PivotBase
GROUP BY GROUPING SETS(
(CaseDefinition),
(UnitName,CaseDefinition),
(UnitName,[Year],[CaseDefinition]),
(UnitName,[Year],[Month],CaseDefinition)
)
)
SELECT pvt.GroupingLevel,
pvt.DisplayName,
pvt.[Case Type 1],
pvt.[Case Type 2],
ISNULL(pvt.[Case Type 1],0) + ISNULL(pvt.[Case Type 2],0) AS [Case Total]
FROM CTE1
PIVOT (
SUM(UnitCount) FOR CaseDefinition IN ([Case Type 1],[Case Type 2])
) pvt
ORDER BY GroupingLevel
<强>解释强>
GROUPING SET( (set1), (set2), (set3) )
定义了汇总级别。对于 UnitID
内的每个唯一组合,然后set1
,然后set2
set3
的计数
GROUPING_ID
是这里最晦涩的功能。把它想象成一个小面具。如果聚合了列,则其位值设置为1.例如:GROUPING_ID(field3, field2, field1, field0)
。如果未聚合所有4,则位掩码为0000 = 0
。如果汇总了field0
,则返回的值为0001 = 1
,依此类推。
您可以将最后一个SELECT替换为SELECT * FROM CTE1
,以查看查询的内部工作情况。
答案 1 :(得分:2)
您可以通过在月份和年份上旋转,然后使用WITH ROLLUP
来到达那里WITH data
AS (SELECT *
FROM (SELECT Dateadd(month, Datediff(month, 0, PCT.dateofdelivery), 0
)
MonthYear,
PCT.unitid,
PCT.unitname
AS
[Unit],
PCT.casedefinition
AS
[Case definition]
FROM pivotbase AS PCT) AS P1
PIVOT ( Count(unitid)
FOR [case definition] IN ([Case type 1],
[Case type 2]) ) AS p2),
rollup
AS (SELECT Month(monthyear) Month,
unit unitX,
Year(monthyear) Year,
Sum([case type 1]) [case type 1],
Sum([case type 2]) [case type 2],
Grouping(unit) GUnit,
Grouping(Month(monthyear)) gm,
Grouping(Year(monthyear)) gy
FROM data
GROUP BY unit,
Year(monthyear),
Month(monthyear) WITH rollup)
SELECT COALESCE(Cast(month AS VARCHAR), Cast(year AS VARCHAR), unitx,
'Grand Total')
Unit,
[case type 1],
[case type 2]
FROM rollup
ORDER BY gunit,
unitx,
year,
gm DESC,
month