Gofr1 在正确的轨道上,但查询存在问题。
1 - 您不想使用开始和结束的 datediff() 作为停止条件。它适用于一整年,但不适用于部分范围。
2 - 我会在键中添加年份,因为这样可以让您处理跨年份的案例。
3 - 在使用年周公用表表达式之前,您需要汇总销售额。否则,您只需使用 WHERE 子句再次抛出空值(订单日期)。
请记住,逻辑上先应用连接,然后应用 where 子句。
下面的代码使用Adventure Works 2012 DW数据库并获得正确答案。
- 对某些数字使用计数表。
- 生成每周日期并计算给定范围的年/周键。
- 从事实表中汇总给定范围的销售额。
- Left 将键连接到销售并将空总计变为零。
代码:
-- Declare start and end date
DECLARE @dte_From datetime = '2005-07-01';
DECLARE @dte_To datetime = '2007-12-31';
-- About 200K numbers
WITH cte_Tally (n) as
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM sys.all_views a
CROSS JOIN sys.all_views b
),
-- Create year/week key
cte_YearWeekKey (MyKey) as
(
SELECT
year(dateadd(week, t.n, @dte_from)) * 1000 +
datepart(week, dateadd(week, t.n, @dte_from)) as MyKey
FROM
cte_Tally as t
WHERE
dateadd(week, t.n, @dte_from) < @dte_To
),
-- Must roll up here
cte_Sales (MyKey, MyTotal) as
(
SELECT
YEAR(F.OrderDate) * 1000 +
DATEPART(WEEK, F.OrderDate) as MyKey,
COUNT(*) as MyTotal
FROM
[AdventureWorksDW2012].[dbo].[FactResellerSales] F
WHERE
F.OrderDate between @dte_From and @dte_To
GROUP BY
YEAR(F.OrderDate) * 1000 +
DATEPART(WEEK, F.OrderDate)
)
-- Join the results
SELECT
K.MyKey, ISNULL(S.MyTotal, 0) as Total
FROM
cte_YearWeekKey as K
LEFT JOIN
cte_Sales as S
ON
k.MyKey = S.MyKey