2012-01-12 79 views
0

我正在开发一个脚本,该脚本将从我们的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 | 
+------------+-------+------+ 

我已经解决了这个问题2个不满意的方面至今:

  1. 填写日期的差距第一,然后计算累积和
  2. 遍历决赛桌的每一个元素,大大节省了最新的非空元素在@u ser变量。

一旦我的表变得足够大,第一个解决方案变得非常低效。第二种解决方案可以完成工作,但我一直在寻找更优雅的解决方案。这里是生成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

为什么要创建不是一个而是两个冗余表? – 2012-01-12 20:35:25

回答

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