用于标识季节性销售项的SQL查询

时间:2010-02-16 22:09:18

标签: sql tsql

我需要一个能够识别季节性销售商品的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()的解决方案 - 我现在正在看它......

2 个答案:

答案 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;