2012-01-12 81 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