2015-05-27 101 views
3

我有一個表,看起來是這樣的:增長百分之計算從以前的行值/減少

|date_start | date_end |amount | 
+------------+-------------+-------+ 
|2015-02-23 | 2015-03-01 |50  | 
|2015-03-02 | 2015-03-08 |50  | 
|2015-03-09 | 2015-03-15 |100 | 
|2015-03-16 | 2015-03-22 |800 | 
|2015-03-23 | 2015-03-29 |50  | 

,我想摸出%的增加/減少爲amount列中,從以前的日期。例如,結果將是這樣的,

|date_start | date_end |amount | perc_change | 
+------------+-------------+-------+-------------+ 
|2015-02-23 | 2015-03-01 |50  | 
|2015-03-02 | 2015-03-08 |50  | 0 
|2015-03-09 | 2015-03-15 |100 | 50 
|2015-03-16 | 2015-03-22 |800 | 700 
|2015-03-23 | 2015-03-29 |50  | -750 

我已經搜索了,並絞死我的腦子幾天了。通常,我只是使用服務器端代碼來做到這一點,但現在我需要在查詢中包含它。

+0

你可以創建[sql小提琴](http://sqlfiddle.com),我做了類似的sql服務器我想我可以調整它到這... –

+0

你確定你正在計算百分比變化? 50到100是100%的變化,100到800是800%的變化... – Arth

+0

這裏的SQL小提琴表,http://sqlfiddle.com/#!9/2c1ec6 – user3768071

回答

3

試試這個:

SELECT t.*, 
amount - (SELECT amount FROM transactions prev WHERE prev.date_end  < t.date_start ORDER BY date_start DESC LIMIT 1) AS changes 
FROM transactions t 
0

它看起來是這樣的,我沒有環境測試這個選擇,但我認爲它應該工作

SELECT t1.date_start, t1.date_end, t1.amount, (t1.amount - t2.amount) as perc_change 
    FROM table1 t1 
     JOIN table1 t2 ON t1.id = t2.id + 1 // here your join to 
    //get next row and calculate this perc_change field 
+0

得到了這個錯誤消息...字段列表中的列'date_start'是含糊不清的 – user3768071

3

如果我們假設上一行總是恰好結束一天電流開始之前(如您的示例數據),那麼您可以使用join。增加的百分比是:

select t.*, 
     100 * (t.amount - tprev.amount)/tprev.amount 
from atable t left join 
    atable tprev 
    on tprev.date_end = t.date_start - interval 1 day; 

然而,你的結果似乎只是有差別,這是容易計算:

select t.*, 
     (t.amount - tprev.amount) as diff 
from atable t left join 
    atable tprev 
    on tprev.date_end = t.date_start - interval 1 day; 
+1

注意到日期相隔一天的好消息!如果這是一致的,它使查詢變得更容易。 – AdamMc331

0

我開始在表中的一個連接每一行在它之後,像這樣:

SELECT m.date_start AS mStart, mt.date_start AS mtStart 
FROM myTable m 
JOIN myTable mT ON m.date_start < mt.date_start AND mt.date_start = (SELECT MIN(date_start) FROM myTable WHERE date_start > m.date_start); 

這將連接表,以便每個行都可以看到以下日期(如果有的話)。如果沒有,則不返回日期。

一旦你有了這些值,你可以調整SELECT查詢之前向您展示之日起的百分比變化,就像這樣:

SELECT 
    mT.date_start AS secondDate, 
    mT.amount - m.amount AS percentChange 
FROM myTable m 
JOIN myTable mT ON m.date_start < mT.date_start AND mt.date_start = (SELECT MIN(date_start) FROM myTable WHERE date_start > m.date_start); 

我想記在這裏,當你說'你的問題中的「百分比差異」,你的預期結果與百分比無關,而只是價值上的差異。如果您需要以不同的方式計算,則可以調整上面的選擇查詢以滿足您的需求。

您將不得不做的最後一件事是將其加回到您的原始表格中,以便一起查看所有值。這必須使用左連接來完成,以便查看錶格的第一個日期。這裏是最後的查詢:

SELECT m.date_start, m.date_end, m.amount, tmp.percentChange 
FROM myTable m 
LEFT JOIN(
    SELECT 
    mT.date_start AS secondDate, 
    mT.amount - m.amount AS percentChange 
    FROM myTable m 
    JOIN myTable mT ON m.date_start < mT.date_start AND mt.date_start = (SELECT MIN(date_start) FROM myTable WHERE date_start > m.date_start) 
) tmp ON tmp.secondDate = m.date_start; 

這裏是一個SQL Fiddle的例子。

+0

McAdam,在SQL小提琴上工作,但通過MySQL執行時,爲什麼我會收到一條錯誤消息...'on子句'中的未知列'mt.date_start'? – user3768071

+0

@ user3768071您可能在其中一個表別名上犯了一個錯字。仔細檢查。 – AdamMc331

+0

這就是我第一次想到的,所以我複製了你的確切表和查詢而沒有做任何改變,我得到了錯誤 – user3768071

0

你的情況下使用mysql VAR系統:

SELECT date_start, date_end, IF(@last IS NOT NULL,ammount - @last , '') as perc_change, @last := amount as amount 
From table 
ORDER BY date_start; 

的VAR @Last被設置在每個通道,perc_change和量之間,列的順序是非常重要的

+0

這並不保證會產生正確的結果:包含用戶變量的表達式的評估順序未定義[請參閱此處](https://dev.mysql.com/doc/refman/5.0/en/user-variables.html) –