MS SQL PIVOT MONTH, QUARTER AND YEAR - 如果存在类似月份值,则显示错误数据的季度
Posted
技术标签:
【中文标题】MS SQL PIVOT MONTH, QUARTER AND YEAR - 如果存在类似月份值,则显示错误数据的季度【英文标题】:MS SQL PIVOT MONTH, QUARTER AND YEAR- The QUARTER Showing Wrong Data for If Similar Month Values Present 【发布时间】:2021-08-18 14:14:55 【问题描述】:我在表中有以下数据结构。
UNITDATE UNIT
2020-01-01 550.00
2020-01-01 777.00
2020-02-01 887.00
2020-02-01 111.00
2020-03-01 501.00
2020-03-01 500.00
2020-04-01 516.00
2020-05-01 516.00
2020-06-01 723.00
但由于 2020-04-01 和 2020-05-01 具有相同的值,因此以下数据透视查询返回了错误的季度 SUM(Q2) 结果。
SELECT SUM([1]) AS Jan, SUM([2]) AS Feb, SUM([3]) AS Mar,SUM(Q1) AS Q1,
SUM([4]) AS Apr, SUM([5]) AS May, SUM([6]) AS Jun, SUM(Q2) AS Q2,
SUM([7]) AS Jul, SUM([8]) AS Aug, SUM([9]) AS Sep, SUM(Q3) AS Q3,
SUM([10]) AS Oct, SUM([11]) AS Nov, SUM([12]) AS Dec, SUM(Q4) AS Q4, SUM([2020]) AS YEARLY
FROM (SELECT
DATEPART(MONTH, UNITDATE) as month,
CAST('Q' + CAST(DATEPART(QUARTER, UNITDATE) AS VARCHAR(1)) AS VARCHAR(2)) AS quarter,
DATEPART(YEAR, UNITDATE) as year,
SUM(UNIT) AS M,
SUM(UNIT) AS Q,
SUM(UNIT) AS Y FROM MyTable WHERE DATEPART(YEAR, UNITDATE) = 2020 GROUP BY UNITDATE) as yearData
PIVOT (SUM(M) FOR month IN ( [1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])) AS PM
PIVOT (SUM(Q) FOR quarter IN ([Q1],[Q2],[Q3],[Q4])) AS PQ
PIVOT (SUM(Y) FOR year IN ([2020])) AS PY;
Jan Feb Mar Q1 Apr May Jun Q2 Jul Aug Sep Q3 Oct Nov Dec Q4 YEARLY
1327.00 998.00 1001.00 3326.00 516.00 516.00 723.00 1239.00 NULL NULL NULL NULL NULL NULL NULL NULL 4565.00
有人遇到过类似的问题吗,请指教。
【问题讨论】:
【参考方案1】:不要使用PIVOT
运算符,它具有限制性且笨重。条件聚合会远更容易:
WITH YourData AS(
SELECT *
FROM(VALUES(CONVERT(date,'2020-01-01'),550.00),
(CONVERT(date,'2020-01-01'),777.00),
(CONVERT(date,'2020-02-01'),887.00),
(CONVERT(date,'2020-02-01'),111.00),
(CONVERT(date,'2020-03-01'),501.00),
(CONVERT(date,'2020-03-01'),500.00),
(CONVERT(date,'2020-04-01'),516.00),
(CONVERT(date,'2020-05-01'),516.00),
(CONVERT(date,'2020-06-01'),723.00))V(UNITDATE,UNIT))
SELECT SUM(CASE DATEPART(MONTH,UNITDATE) WHEN 1 THEN UNIT END) AS Jan,
SUM(CASE DATEPART(MONTH,UNITDATE) WHEN 2 THEN UNIT END) AS Feb,
SUM(CASE DATEPART(MONTH,UNITDATE) WHEN 3 THEN UNIT END) AS Mar,
SUM(CASE WHEN DATEPART(MONTH,UNITDATE) BETWEEN 1 AND 3 THEN UNIT END) AS Q1,
SUM(CASE DATEPART(MONTH,UNITDATE) WHEN 4 THEN UNIT END) AS Apr,
-- You get the idea
SUM(UNIT) AS Yearly
FROM YourData
WHERE UNITDATE >= '20200101'
AND UNITDATE < '20210101';
【讨论】:
谢谢,但是在性能方面,pivot 更适合大型数据集,对吧?我在上面的帖子中分享了一部分数据。 为什么你认为PIVOT
会“更快”?
不确定,我没有比较这些,但假设它的 CTE 支点会做得更好。对吗?
CTE 只是一个表达式。写得不好的表达式会阻碍性能,但这不是问题所在。如果您在UNITDATE
上有一个索引,则该查询INCLUDE
s UNIT
可能会非常快。如果您说PIVOT
更快,则需要使用查询计划来证明这一点。
谢谢你,我也是 SQL 查询的新手——我没有得到你的答案“查询,只要你在 UNITDATE 上有一个包含 UNIT 的索引可能会很快”有什么办法吗用我当前的数据集实现这一目标以上是关于MS SQL PIVOT MONTH, QUARTER AND YEAR - 如果存在类似月份值,则显示错误数据的季度的主要内容,如果未能解决你的问题,请参考以下文章