2014-03-06 53 views
1

我創建了結構和樣本數據here。我不知道如何計算隨時間推移的變化。計算隨時間變化的百分比

我想要的結果集爲:

a | % growth 
abc | 4.16 
def | 0.83 
hig | -0.2 

的百分比變化爲(最後一個值 - 第一個值)/天:

a | % growth 
abc | (30-5)/6 
def | (6-1)/6 
hig | (4-5)/5 

我想:

SELECT a.*, 
     b.val, 
     c.val 
FROM (SELECT a, 
       Min(dt) AS lowerDt, 
       Max(dt) AS upperDt 
     FROM tt 
     GROUP BY a) a 
     LEFT JOIN tt b 
       ON b.dt = a.lowerdt 
       AND b.a = a.a 
     LEFT JOIN tt c 
       ON c.dt = a.upperdt 
       AND b.a = a.a 

如果可能的話,我想避免CTE。

+0

爲什麼你要避免使用CTE?在許多情況下,它們使代碼更容易閱讀。 – MatBailie

+1

也許爲了可能的移植到MySQL? – ely

+0

@MatBailie到其他DBMS(不是MySQL)的可移植性 – user3242205

回答

1

你不想要minmax,你真的想要firstlast

我這樣做的一種方法是使用ROW_NUMBER()來告訴我從開始或結束的位置。然後使用MAX(CASE WHEN pos=1 THEN x ELSE null END)來獲得我想要的值。

SELECT 
    a, 
    MAX(CASE WHEN pos_from_first = 1 THEN dt ELSE NULL END) AS first_date, 
    MAX(CASE WHEN pos_from_final = 1 THEN dt ELSE NULL END) AS final_date, 
    MAX(CASE WHEN pos_from_first = 1 THEN val ELSE NULL END) AS first_value, 
    MAX(CASE WHEN pos_from_final = 1 THEN val ELSE NULL END) AS final_value, 
    100 
    * 
    CAST(MAX(CASE WHEN pos_from_final = 1 THEN val ELSE NULL END) AS DECIMAL(9,6)) 
/
    CAST(MAX(CASE WHEN pos_from_first = 1 THEN val ELSE NULL END) AS DECIMAL(9,6)) 
    - 
    100              AS perc_change 
FROM 
(
    SELECT 
    ROW_NUMBER() OVER (PARTITION BY a ORDER BY dt ASC) AS pos_from_first, 
    ROW_NUMBER() OVER (PARTITION BY a ORDER BY dt DESC) AS pos_from_final, 
    * 
    FROM 
    tt 
) 
    AS ordered 
GROUP BY 
    a 

http://sqlfiddle.com/#!6/ad95d/11

+0

編輯將流氓'ASC'改爲'DESC',修復百分比等 – MatBailie

+0

我在測試時注意到窗口中的排序。 – user3242205