2015-11-02 157 views
0

我有歷史股價數據,如下所示。我想要生成一個新表格,其中包含最近一天價格和前一天價格的每個代碼。什麼是最好的方法來做到這一點?我的數據庫是Postgres。SQL查詢選擇今天和前一天的價格

+---------+------------+------------+ 
| ticker | price  | date  | 
+---------+------------+------------| 
| AAPL |   6 | 10-23-2015 | 
| AAPL |   5 | 10-22-2015 | 
| AAPL |   4 | 10-21-2015 | 
| AXP |   5 | 10-23-2015 | 
| AXP |   3 | 10-22-2015 | 
| AXP |   5 | 10-21-2015 | 
+------- +-------------+------------+ 
+0

使用'lag'或'lead'窗口函數。有關更多信息,請參閱手冊。 (我沒有downvote,順便說一句)。 –

回答

1

你可以做這樣的事情:

with ranking as (
    select ticker, price, dt, 
    rank() over (partition by ticker order by dt desc) as rank 
    from stocks 
) 
select * from ranking where rank in (1,2); 

例子:http://sqlfiddle.com/#!15/e45ea/3

結果你的例子看起來像這個:

| ticker | price |      dt | rank | 
|--------|-------|---------------------------|------| 
| AAPL |  6 | October, 23 2015 00:00:00 | 1 | 
| AAPL |  5 | October, 22 2015 00:00:00 | 2 | 
| AXP |  5 | October, 23 2015 00:00:00 | 1 | 
| AXP |  3 | October, 22 2015 00:00:00 | 2 | 

如果您的表格很大並且存在性能問題,請使用where限制數據持續30天左右。

1

最好的辦法是使用窗口函數和聚合case語句,該語句用於在數據上創建數據透視表。

你可以看到更多的窗口功能在這裏:http://www.postgresql.org/docs/current/static/tutorial-window.html

下面是在那裏你可能需要前往回答你的問題(抱歉,我無法驗證它,由於沒有一個Postgres數據庫的僞代碼版本建立)。

Select 
ticker, 
SUM(CASE WHEN rank = 1 THEN price ELSE 0 END) today, 
SUM(CASE WHEN rank = 2 THEN price ELSE 0 END) yesterday 
FROM (
SELECT 
ticker, 
price, 
date, 
rank() OVER (PARTITION BY ticker ORDER BY date DESC) as rank 
FROM your_table) p 
WHERE rank in (1,2) 
GROUP BY ticker. 

編輯 - 更新了case語句與 '其他'