如何获取每个产品/进入日期的最近4周的数据

时间:2011-03-02 14:12:42

标签: mysql sql

我有一个问题,我有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 个答案:

答案 0 :(得分:2)

虽然以逗号分隔的列表是将一组值传递给查询的便捷方式,但在这样的情况下它是不适合的,在这种情况下,要求请求的每个值都应存在于数据集中。因此,不应将其用作列表,而应将值设置为数据列,即行集。这样就可以将所有这些包含在结果集中。

以上内容适用于查询中的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 :(得分:1)

我会添加一个简单的表格,其中包含从开始年份到结束年份的所有可用日期 - 您在销售表格中的日期范围。

然后我会按日期加入表格。

在我将给定日期作为上限的地方。

我会按日期订购。

然后简单地说:

select top 4

加入和选择当然是在给定日期的前期。

它会更快更有效......