PIVOT 不在 DENSE_RANK 列上工作
PIVOT Not Working on a DENSE_RANK Column
我正在编写一份报告,其中提供了每日运营数据的每周总计。报告顶部将有 8 周作为列。每一排都是一辆车。诸如日期范围之类的变量最终将变成动态的,在我开发它的时候,这现在有点硬编码。 8 周可以保持硬编码。
这非常有效:
SELECT vehicle, [2] AS W2, [3] AS W3, [4] AS W4, [5] AS W5, [6] AS W6, [7] AS W7, [8] AS W8, [9] AS W9
FROM
(
SELECT
Vehicle
,datepart(week,recordedoneffective) as WeekNum
,sum(totalweight ) AS TotalWeight
from vw_visit_details v, vw_food_stats f
where v.VisitId = f.VisitId
and recordedoneffective between '2015-01-05' and '2015-03-01'
group by vehicle,datepart(week,recordedoneffective)
) src
PIVOT
(
SUM(TotalWeight)
FOR WeekNum IN ([2],[3],[4],[5],[6],[7],[8],[9])
) pvt
ORDER BY pvt.vehicle
结果:
Vehicle W2 W3 W4 W5 W6 W7 W8 W9
Apples - D44CW 2603 7840 3200 1540 3516 2828 3217 3911
Bananas - 664SEC 4063 5004 5935 8734 8333 8663 4591 7807
Capsicum - YPD094 4699 6191 6423 4560 5742 7004 7204 5347
但是,由于 WeekNum 会根据指定的日期而变化,我想将 WeekNum 转换为一个排名,该排名将始终保持不变。为此,我使用了 DENSE_RANK,因此将 8 周数字(在本例中为 2-9)的范围转换为数字 1-8。
SELECT vehicle, [1] AS W1, [2] AS W2, [3] AS W3, [4] AS W4, [5] AS W5, [6] AS W6, [7] AS W7, [8] AS W8
FROM
(
select
Vehicle
,datepart(week,recordedoneffective) as WeekNum
,dense_rank() OVER ( ORDER BY datepart (week,recordedoneffective) ) AS WeekSeq
,sum(totalweight ) AS TotalWeight
from vw_visit_details v, vw_food_stats f
where v.VisitId = f.VisitId
and recordedoneffective between '2015-01-05' and '2015-03-01'
group by vehicle, datepart(week,recordedoneffective)
) src
PIVOT
(
SUM(TotalWeight)
FOR WeekSeq IN ([1],[2],[3],[4],[5],[6],[7],[8])
) pvt
ORDER BY pvt.vehicle
请注意,列名现在是 1-8 而不是 2-9,并且数据透视列已更改。但是现在其余的集没有正确旋转。
Vehicle W1 W2 W3 W4 W5 W6 W7 W8
Apples - D44CW 2603 NULL NULL NULL NULL NULL NULL NULL
Apples - D44CW NULL 7840 NULL NULL NULL NULL NULL NULL
Apples - D44CW NULL NULL 3200 NULL NULL NULL NULL NULL
Apples - D44CW NULL NULL NULL 1540 NULL NULL NULL NULL
Apples - D44CW NULL NULL NULL NULL 3516 NULL NULL NULL
Apples - D44CW NULL NULL NULL NULL NULL 2828 NULL NULL
Apples - D44CW NULL NULL NULL NULL NULL NULL 3217 NULL
Apples - D44CW NULL NULL NULL NULL NULL NULL NULL 3911
Bananas - 664SEC 4063 NULL NULL NULL NULL NULL NULL NULL
所以基本上,枢轴不再旋转了。两个查询的内部 src
结果集完全相同(除了添加新列)- 返回相同数量的结果,没有新的空值等。
我想也许我需要 GROUP BY
dense_rank() OVER ( ORDER BY datepart(week,recordedoneffective) )
列,但您不能按此分组。还认为我应该尝试删除现在未使用的 datepart(week,recordedoneffective)
计算列 - 事实证明,为了在 OVER
子句中使用它,仍然必须将它放在那里。
为什么这个枢轴不起作用?大概我可以用更动态的方式解决这个问题 SQL,但我看不出为什么这不起作用。
您想 GROUP BY
在执行 DENSE_RANK()
之前的一个步骤中,因为您没有在 PIVOT
输出中使用 WeekNum
。
;WITH cte AS (SELECT Vehicle
,datepart(week,recordedoneffective) as WeekNum
,sum(totalweight ) AS TotalWeight
FROM vw_visit_details v, vw_food_stats f
WHERE v.VisitId = f.VisitId
and recordedoneffective between '2015-01-05' and '2015-03-01'
GROUP BY vehicle, datepart(week,recordedoneffective)
)
,cte2 AS (SELECT vehicle
,dense_rank() OVER ( ORDER BY WeekNum ) AS WeekSeq
,TotalWeight
FROM cte
)
SELECT vehicle, [1] AS W1, [2] AS W2, [3] AS W3, [4] AS W4, [5] AS W5, [6] AS W6, [7] AS W7, [8] AS W8
FROM cte2
PIVOT (SUM(TotalWeight) FOR WeekSeq IN ([1],[2],[3],[4],[5],[6],[7],[8])) pvt
ORDER BY pvt.vehicle
您的 CTE 有四列:Vehicle、WeekNum、WeekSeq 和 TotalWeight。 PIVOT 子句引用了最后两个;这意味着枢轴的隐式分组基于前两列。因此,对于 Vehicle 和 WeekNum 的每个唯一组合,您都会得到一行。这在您的结果集中并不清楚,因为您没有选择 WeekNum。
对于您的情况,答案很简单 - 从 CTE 中删除 WeekNum,因为您实际上并没有使用它。
我正在编写一份报告,其中提供了每日运营数据的每周总计。报告顶部将有 8 周作为列。每一排都是一辆车。诸如日期范围之类的变量最终将变成动态的,在我开发它的时候,这现在有点硬编码。 8 周可以保持硬编码。
这非常有效:
SELECT vehicle, [2] AS W2, [3] AS W3, [4] AS W4, [5] AS W5, [6] AS W6, [7] AS W7, [8] AS W8, [9] AS W9
FROM
(
SELECT
Vehicle
,datepart(week,recordedoneffective) as WeekNum
,sum(totalweight ) AS TotalWeight
from vw_visit_details v, vw_food_stats f
where v.VisitId = f.VisitId
and recordedoneffective between '2015-01-05' and '2015-03-01'
group by vehicle,datepart(week,recordedoneffective)
) src
PIVOT
(
SUM(TotalWeight)
FOR WeekNum IN ([2],[3],[4],[5],[6],[7],[8],[9])
) pvt
ORDER BY pvt.vehicle
结果:
Vehicle W2 W3 W4 W5 W6 W7 W8 W9
Apples - D44CW 2603 7840 3200 1540 3516 2828 3217 3911
Bananas - 664SEC 4063 5004 5935 8734 8333 8663 4591 7807
Capsicum - YPD094 4699 6191 6423 4560 5742 7004 7204 5347
但是,由于 WeekNum 会根据指定的日期而变化,我想将 WeekNum 转换为一个排名,该排名将始终保持不变。为此,我使用了 DENSE_RANK,因此将 8 周数字(在本例中为 2-9)的范围转换为数字 1-8。
SELECT vehicle, [1] AS W1, [2] AS W2, [3] AS W3, [4] AS W4, [5] AS W5, [6] AS W6, [7] AS W7, [8] AS W8
FROM
(
select
Vehicle
,datepart(week,recordedoneffective) as WeekNum
,dense_rank() OVER ( ORDER BY datepart (week,recordedoneffective) ) AS WeekSeq
,sum(totalweight ) AS TotalWeight
from vw_visit_details v, vw_food_stats f
where v.VisitId = f.VisitId
and recordedoneffective between '2015-01-05' and '2015-03-01'
group by vehicle, datepart(week,recordedoneffective)
) src
PIVOT
(
SUM(TotalWeight)
FOR WeekSeq IN ([1],[2],[3],[4],[5],[6],[7],[8])
) pvt
ORDER BY pvt.vehicle
请注意,列名现在是 1-8 而不是 2-9,并且数据透视列已更改。但是现在其余的集没有正确旋转。
Vehicle W1 W2 W3 W4 W5 W6 W7 W8
Apples - D44CW 2603 NULL NULL NULL NULL NULL NULL NULL
Apples - D44CW NULL 7840 NULL NULL NULL NULL NULL NULL
Apples - D44CW NULL NULL 3200 NULL NULL NULL NULL NULL
Apples - D44CW NULL NULL NULL 1540 NULL NULL NULL NULL
Apples - D44CW NULL NULL NULL NULL 3516 NULL NULL NULL
Apples - D44CW NULL NULL NULL NULL NULL 2828 NULL NULL
Apples - D44CW NULL NULL NULL NULL NULL NULL 3217 NULL
Apples - D44CW NULL NULL NULL NULL NULL NULL NULL 3911
Bananas - 664SEC 4063 NULL NULL NULL NULL NULL NULL NULL
所以基本上,枢轴不再旋转了。两个查询的内部 src
结果集完全相同(除了添加新列)- 返回相同数量的结果,没有新的空值等。
我想也许我需要 GROUP BY
dense_rank() OVER ( ORDER BY datepart(week,recordedoneffective) )
列,但您不能按此分组。还认为我应该尝试删除现在未使用的 datepart(week,recordedoneffective)
计算列 - 事实证明,为了在 OVER
子句中使用它,仍然必须将它放在那里。
为什么这个枢轴不起作用?大概我可以用更动态的方式解决这个问题 SQL,但我看不出为什么这不起作用。
您想 GROUP BY
在执行 DENSE_RANK()
之前的一个步骤中,因为您没有在 PIVOT
输出中使用 WeekNum
。
;WITH cte AS (SELECT Vehicle
,datepart(week,recordedoneffective) as WeekNum
,sum(totalweight ) AS TotalWeight
FROM vw_visit_details v, vw_food_stats f
WHERE v.VisitId = f.VisitId
and recordedoneffective between '2015-01-05' and '2015-03-01'
GROUP BY vehicle, datepart(week,recordedoneffective)
)
,cte2 AS (SELECT vehicle
,dense_rank() OVER ( ORDER BY WeekNum ) AS WeekSeq
,TotalWeight
FROM cte
)
SELECT vehicle, [1] AS W1, [2] AS W2, [3] AS W3, [4] AS W4, [5] AS W5, [6] AS W6, [7] AS W7, [8] AS W8
FROM cte2
PIVOT (SUM(TotalWeight) FOR WeekSeq IN ([1],[2],[3],[4],[5],[6],[7],[8])) pvt
ORDER BY pvt.vehicle
您的 CTE 有四列:Vehicle、WeekNum、WeekSeq 和 TotalWeight。 PIVOT 子句引用了最后两个;这意味着枢轴的隐式分组基于前两列。因此,对于 Vehicle 和 WeekNum 的每个唯一组合,您都会得到一行。这在您的结果集中并不清楚,因为您没有选择 WeekNum。
对于您的情况,答案很简单 - 从 CTE 中删除 WeekNum,因为您实际上并没有使用它。