Как получить данные за последние 4 недели по отдельным продуктам / дате поступления - PullRequest
1 голос
/ 02 марта 2011

У меня проблема с тем, что у меня есть 4 дня в качестве входных данных, и я должен получить значения за последние 4 недели для каждой

Эти последние 4 недели не означают самые последние 4 недели, для которых у меня естьрешение.

    SELECT prodno, 
           ardate8n, 
           selloff1 
    FROM   sales s 
           JOIN ( SELECT CAST(DATE_SUB('2011-02-27', INTERVAL 1 WEEK) AS DECIMAL(8,0)) AS wdt, '2011-02-27' AS adt
 UNION ALL
 SELECT CAST(DATE_SUB('2011-02-27', INTERVAL 2 WEEK) AS DECIMAL(8,0)) AS wdt, '2011-02-27' AS adt
 UNION ALL
 SELECT CAST(DATE_SUB('2011-02-27', INTERVAL 3 WEEK) AS DECIMAL(8,0)) AS wdt, '2011-02-27' AS adt
 UNION ALL
 SELECT CAST(DATE_SUB('2011-02-27', INTERVAL 4 WEEK) AS DECIMAL(8,0)) AS wdt, '2011-02-27' AS adt

UNION ALL

 SELECT CAST(DATE_SUB('2011-02-26', INTERVAL 1 WEEK) AS DECIMAL(8,0)) AS wdt, '2011-02-26' AS adt
 UNION ALL
 SELECT CAST(DATE_SUB('2011-02-26', INTERVAL 2 WEEK) AS DECIMAL(8,0)) AS wdt, '2011-02-26' AS adt
 UNION ALL
 SELECT CAST(DATE_SUB('2011-02-26', INTERVAL 3 WEEK) AS DECIMAL(8,0)) AS wdt, '2011-02-26' AS adt
 UNION ALL
 SELECT CAST(DATE_SUB('2011-02-26', INTERVAL 4 WEEK) AS DECIMAL(8,0)) AS wdt, '2011-02-26' AS adt

UNION ALL

 SELECT CAST(DATE_SUB('2011-02-25', INTERVAL 1 WEEK) AS DECIMAL(8,0)) AS wdt, '2011-02-25' AS adt
 UNION ALL
 SELECT CAST(DATE_SUB('2011-02-25', INTERVAL 2 WEEK) AS DECIMAL(8,0)) AS wdt, '2011-02-25' AS adt
 UNION ALL
 SELECT CAST(DATE_SUB('2011-02-25', INTERVAL 3 WEEK) AS DECIMAL(8,0)) AS wdt, '2011-02-25' AS adt
 UNION ALL
 SELECT CAST(DATE_SUB('2011-02-25', INTERVAL 4 WEEK) AS DECIMAL(8,0)) AS wdt, '2011-02-25' AS adt

UNION ALL

 SELECT CAST(DATE_SUB('2011-02-24', INTERVAL 1 WEEK) AS DECIMAL(8,0)) AS wdt, '2011-02-24' AS adt
 UNION ALL
 SELECT CAST(DATE_SUB('2011-02-24', INTERVAL 2 WEEK) AS DECIMAL(8,0)) AS wdt, '2011-02-24' AS adt
 UNION ALL
 SELECT CAST(DATE_SUB('2011-02-24', INTERVAL 3 WEEK) AS DECIMAL(8,0)) AS wdt, '2011-02-24' AS adt
 UNION ALL
 SELECT CAST(DATE_SUB('2011-02-24', INTERVAL 4 WEEK) AS DECIMAL(8,0)) AS wdt, '2011-02-24' AS adt) days 
             ON s.ardate8n = days.wdt 
    WHERE  custno = 38726 
           AND deptno = 0 
           AND Find_in_set(prodno, '0020,0064,0070,0073,0096') > 0 
    ORDER by prodno,adt,ardate8n;

Как видите, последние 4 недели у меня жестко запрограммированы.Это считывает только последние 4 недели на продукт / на дату поступления, и если одна или несколько недель пропущены записи, я не получаю 4 строки.

Так что мне нужно получить это динамически с некоторым ограничениемв этом.sales.ardate8n дает, если есть запись для данного дня.

Возвращает следующие данные

0006, '2011-03-03', 20110127, 0
0006, '2011-03-03', 20110203, 0
0006, '2011-03-03', 20110210, 0
0006, '2011-03-04', 20110128, 0
0006, '2011-03-04', 20110204, 0
0006, '2011-03-05', 20110129, 0
0006, '2011-03-05', 20110205, 0
0006, '2011-03-05', 20110212, 0
0006, '2011-03-05', 20110219, 0

Как вы видите для даты входа 2011-03-03 продукт имеет только 3 строки дляв тот же день неделии на дату поступления 2011-03-04 продукт имеет только 2 строки для одного и того же дня недели.

Ответы [ 2 ]

2 голосов
/ 29 июня 2011

Хотя список через запятую является удобным способом передачи набора значений в запрос, он непригоден в ситуациях, подобных этой, где требуется, чтобы каждое запрашиваемое значение присутствовало в наборе данных. Таким образом, вместо использования в качестве списка, значения должны быть сделаны столбцом данных, набором строк. Это позволило бы включить их все в итоговый набор.

Вышеприведенное относится к списку prodno значений в вашем запросе, но то же самое относится и к датам.

Вот пример того, как можно было бы выполнить требования, если входные данные были преобразованы в наборы данных:

SELECT
  p.prodno,
  d.date,
  CAST(DATESUB(d.date, INTERVAL (w.weeksAgo) WEEK) AS DECIMAL(8, 0)) AS ardate8n,
  s.selloff1

FROM       (SELECT @date1 AS date
  UNION ALL SELECT @date2
  UNION ALL SELECT @date3
  UNION ALL SELECT @date4) d

CROSS JOIN (SELECT 1 AS weeksAgo
  UNION ALL SELECT 2
  UNION ALL SELECT 3
  UNION ALL SELECT 4) w

CROSS JOIN (SELECT '0020' AS prodno
  UNION ALL SELECT '0064'
  UNION ALL SELECT '0070'
  UNION ALL SELECT '0073'
  UNION ALL SELECT '0096') p

LEFT JOIN sales s
  ON s.ardate8n = CAST(DATESUB(d.date, INTERVAL (w.weeksAgo) WEEK) AS DECIMAL(8, 0))
 AND s.prodno   = p.prodno
 AND s.custno   = 38726 
 AND s.deptno   = 0
1 голос
/ 29 июня 2011

Я бы добавил простую таблицу со всеми доступными датами от начального года до конца года - ваш диапазон дат в таблице продаж.

тогда я бы присоединился к таблицам по дате.

Там, где я поставлю данную дату как верхний предел.

Я закажу по дате.

, а затем просто:

select top 4

соединение и выбор будут, конечно, foreach указанных дат.

Это будет намного быстрее и эффективнее ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...