2014-03-31 85 views
2

我知道這已被問過。但是,我在SQL和MySQL方面比較新,所以我對其他答案感到困惑。計算兩行之間的百分比變化

假設我有一個歷史財務數據表,並且我有多個記錄。

Date  | Close Price | % Change 
2014-03-25 | 3.58  | ? 
2014-03-24 | 3.57  | ? 
2014-03-21 | 3.61  | ? 

我有表中的日期和收盤價。我想每天都找到%的變化。例如,從2014-03-24到2014-03-25約爲+ 0.28%。

我完全停留在如何爲所有記錄執行此操作而無需運行大量單個查詢。我認爲這是某種加入,但這是我感到困惑的地方,因爲我之前沒做過這些。

+0

老實說,我還沒有執行任何事情。我能夠做的唯一的事情就是獲取值,使用PHP進行計算並插入結果。但是,這可能會導致每行2個查詢,並且我有很多行... –

回答

6

像這樣的事情會做到這一點,我認爲

SELECT x.Date, x.Close_Price, (((x.Close_Price/y.Close_Price) - 1) * 100) AS '% Change' 
FROM 
(
    SELECT a.Date AS aDate, MAX(b.Date) AS aPrevDate 
    FROM SomeTable a 
    INNER JOIN SomeTable b 
    WHERE a.Date > b.Date 
    GROUP BY a.Date 
) Sub1 
INNER JOIN SomeTable x ON Sub1.aDate = x.Date 
INNER JOIN SomeTable y ON Sub1.aPrevDate = y.Date 
ORDER BY x.Close_Price DESC 

的時候,天都沒有一個接一個的(例如,對於非加工時間想記錄)這將應付。

子查詢獲取每個日期,並且最大日期小於它。然後將它與表格連接起來,以獲取該日期和前一個日期的完整記錄,然後可以完成計算。

編輯 - 和更新在此基礎上選擇: -

UPDATE treasury x 
INNER JOIN 
(
    SELECT a.Date AS aDate, MAX(b.Date) AS aPrevDate 
    FROM treasury a 
    INNER JOIN treasury b 
    WHERE a.Date > b.Date 
    GROUP BY a.Date 
) Sub1 ON Sub1.aDate = x.Date 
INNER JOIN treasury y ON Sub1.aPrevDate = y.Date 
SET x.PercentChange = (((x.Close_Price/y.Close_Price) - 1) * 100) 
+0

對不起,我仍然開始使用SQL。在我的情況下,如果我的表名是「國庫」,我是否會將「SomeTable」替換爲「國庫」? –

+0

無視最新評論。我替換了表名和正確的列名,這就是我得到的,1個結果: 2014-03-27 | 3.51 | -1.126759503952346 這是正確的百分比變化。但是,這並沒有修改實際的表,因爲沒有調用UPDATE。我將如何考慮? –

+0

您可以基於此進行更新。但是,您想要更新哪些字段? – Kickstart

2
Select S1.Date as Today, (S1.ClosePrice - S2.ClosePrice)/S2.ClosePrice as Change 
FROM Stock as S1 INNER JOIN Stock as S2 
ON S1.Date = (S2.Date+1) 
+0

我在其他問題上看到了類似的答案。我的主要困惑是:什麼是「S1」,「S2」等? –

+0

這是做什麼用的?它如何爲這個問題提供正確的答案?解釋你在做什麼,以及它是如何工作的。 – Jojodmo

+0

S1和S2是表別名。該查詢是一個自聯接。 –

0

PostgreSQL有一個方便的窗函數

lag(value anyelement [, offset integer [, default anyelement ]]) 

簡化了這個問題(因爲我剛剛發現我自己)到

SELECT 'Date', 
     'Close Price', 
     (('Close Price'/lag('Close Price', 1) OVER (ORDER BY 'Date')) - 1) * 100 AS percentage_change 
FROM treasury 
ORDER BY 'Date';