SQL-запрос для определения позиций сезонных продаж - PullRequest
2 голосов
/ 17 февраля 2010

Мне нужен запрос SQL, который идентифицирует позиции сезонных продаж.

Моя таблица имеет следующую структуру -

ProdId    WeekEnd     Sales
234       23/04/09    543.23
234       30/04/09     12.43
432       23/04/09      0.00
etc

Мне нужен SQL-запрос, который будет возвращать все ProdId, которые имеют 26 недель подряд 0 продаж. Я использую SQL Server 2005. Большое спасибо!

Обновление: Коллега предложил решение с использованием rank () - сейчас я его смотрю ...

Ответы [ 2 ]

1 голос
/ 17 февраля 2010

Вот моя версия:

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> 0 ':

OR s1.WeekEnd = (SELECT MIN(WeekEnd) FROM Sales WHERE ProdID = s1.ProdID)

Это значительно замедлит запрос, но гарантирует, что первая неделя «зарегистрированных» продаж всегда будет учитываться.

0 голосов
/ 17 февраля 2010
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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...