填写日期差距与最近的价值

时间:2012-01-12 20:26:14

标签: mysql sql

我正在我的公司开发一个脚本,它将从我们的SCM中获取有关源代码活动的信息,例如一段时间内给定产品的更改行数。在同一天内发生的给定产品的所有更改将合并到mySQL表中的单个记录中,如下所示:

+------------+-------+------+
| date       | prod  | line |
+------------+-------+------+
| 2011-11-25 | prod2 |  471 |
| 2011-11-28 | prod2 |  389 |
+------------+-------+------+

然后,我使用内部联接和求和来复制具有累积结果的表:

+------------+-------+------+
| date       | prod  | line |
+------------+-------+------+
| 2011-11-25 | prod2 |  471 |
| 2011-11-28 | prod2 |  860 |
+------------+-------+------+

现在,我想创建一个每个产品每天都有一条记录的表。我已经能够通过加入日历表来做到这一点。但是,在创建新记录的位置,字段应填充该产品的最新累积值,而不是某些硬编码的默认值,如NULL或0:

+------------+-------+------+
| date       | prod  | line |
+------------+-------+------+
| 2011-11-25 | prod2 |  471 |
| 2011-11-26 | prod2 |  471 |
| 2011-11-27 | prod2 |  471 |
| 2011-11-28 | prod2 |  860 |
+------------+-------+------+

到目前为止,我已经以两种令人不满意的方式解决了这个问题:

  1. 首先填写日期空白,然后计算累计金额
  2. 遍历最终表的每个元素,将最新的非null元素保存在@user变量中。
  3. 一旦我的桌子变得足够大,第一个解决方案变得非常低效。第二个解决方案完成了工作,但我一直在努力寻找更优雅的解决方案。以下是使用NULL生成表的代码:

    INSERT INTO final SELECT d.date,f.prod,p.line
    FROM calendar AS d
    CROSS JOIN
        (SELECT DISTINCT prod FROM cumulative) AS f
    LEFT JOIN cumulative AS p USING (date,prod) ;
    

    有什么想法吗?我正在使用MySQL。

1 个答案:

答案 0 :(得分:0)

似乎最明智的做法是每天存储一行,如果没有更改行则为零。这将消除在日历表上加入的需要。

所以代替你的源表看起来像这样

+------------+-------+------+
| date       | prod  | line |
+------------+-------+------+
| 2011-11-25 | prod2 |  471 |
| 2011-11-28 | prod2 |  389 |
+------------+-------+------+

它看起来像这样。

+------------+-------+------+
| date       | prod  | line |
+------------+-------+------+
| 2011-11-25 | prod2 |  471 |
| 2011-11-26 | prod2 |    0 |
| 2011-11-27 | prod2 |    0 |
| 2011-11-28 | prod2 |  389 |
+------------+-------+------+

至于运行总和本身,您的报表编写者可能比SQL更快地执行此操作。如果MySQL支持窗口函数,你只需编写类似

的东西
select date, prod, 
       sum(line) over (partition by prod order by date)
from prod

尽管如此,即便如此,您的报告撰稿人可能会更快。

在不支持窗口函数的平台上,您只需要在子查询中求和。

select p1.prod, p1.date, 
       (select sum(line) from prod 
        where prod = p1.prod and date <= p1.date) as num_lines
from prod p1
order by p1.prod, p1.date