我需要一个能够识别季节性销售商品的SQL查询。
我的桌子有以下结构 -
ProdId WeekEnd Sales
234 23/04/09 543.23
234 30/04/09 12.43
432 23/04/09 0.00
etc
我需要一个SQL查询,它将返回连续26周销售的所有ProdId。我正在运行SQL Server 2005.非常感谢!
更新:一位同事建议使用rank()的解决方案 - 我现在正在看它......
答案 0 :(得分:1)
这是我的版本:
DECLARE @NumWeeks int
SET @NumWeeks = 26
SELECT s1.ProdID, s1.WeekEnd, COUNT(*) AS ZeroCount
FROM Sales s1
INNER JOIN Sales s2
ON s2.ProdID = s1.ProdID
AND s2.WeekEnd >= s1.WeekEnd
AND s2.WeekEnd <= DATEADD(WEEK, @NumWeeks + 1, s1.WeekEnd)
WHERE s1.Sales > 0
GROUP BY s1.ProdID, s1.WeekEnd
HAVING COUNT(*) >= @NumWeeks
现在,这是一个关键假设,即没有重复的条目(每个产品每周只有1个),并且每周实际输入新数据。考虑到这些假设,如果我们看一下非零销售周之后的27周并发现有26个总周并且销售额为零,那么我们可以从逻辑上推断他们必须是26 连续周。
请注意,这将忽略从一开始就没有销售额的产品;必须有一个非零周来锚定它。如果您想要包含自开始以来没有销售的产品,那么在`WHERE s1.Sales&gt;之后添加以下行。 0' :
OR s1.WeekEnd = (SELECT MIN(WeekEnd) FROM Sales WHERE ProdID = s1.ProdID)
这将大大减慢查询速度,但保证将始终考虑“记录”销售的第一周。
答案 1 :(得分:0)
SELECT DISTINCT
s1.ProdId
FROM (
SELECT
ProdId,
ROW_NUMBER() OVER (PARTITION BY ProdId ORDER BY WeekEnd) AS rownum,
WeekEnd
FROM Sales
WHERE Sales <> 0
) s1
INNER JOIN (
SELECT
ProdId,
ROW_NUMBER() OVER (PARTITION BY ProdId ORDER BY WeekEnd) AS rownum,
WeekEnd
FROM Sales
WHERE Sales <> 0
) s2
ON s1.ProdId = s2.ProdId
AND s1.rownum + 1 = s2.rownum
AND DateAdd(WEEK, 26, s1.WeekEnd) = s2.WeekEnd;