2016-04-15 34 views
2

我有一個是建立了如下表:月度價格數據:開放式,高,低和關閉

dpTicker dpDate  dpOpen  dpHigh  dpLow  dpClose  dpVolume dpAdjClose dpCreated   dpModified 
GLE.PA  2016-02-01 35.39  35.455  34.375  34.785  2951300  34.785  2016-02-06 13:33:40 2016-02-06 13:33:40 
GLE.PA  2016-02-02 34.515  34.565  32.165  32.575  7353600  32.575  2016-02-06 13:33:40 2016-02-06 13:33:40 
GLE.PA  2016-02-03 32.4  32.495  30.885  31.6  7007000  31.6  2016-02-06 13:33:40 2016-02-06 13:33:40 
GLE.PA  2016-02-04 32.075  32.38  30.67  31.98  8181000  31.98  2016-02-06 13:33:40 2016-02-06 13:33:40 
GLE.PA  2016-02-05 32.55  33.0  31.86  32.11  7056700  32.11  2016-02-06 13:33:40 2016-02-06 13:33:40 

的數據是每天的股價信息和表中包含數百個代號(如GLE。 PA)。每個代碼(例如GLE.PA)都有一個用於每個「工作日」的條目。

我的目標是從每日價格數據表中查詢每月價格摘要。月度數據構建如下:

  1. 月份開放:dp在每月的第一個營業日開放;
  2. 月份最高值:本月的最高值(dpHigh)
  3. 月份最低值:本月的最低值(dpLow)
  4. 月份關閉:dpClose在該月的最後一個營業日期。

我管理在SQLite3的使用下面的查詢來查詢特定月份的數據:

SELECT 
    strftime ('%Y-%m', dpDate) AS month,  
    (SELECT dpOpen 
     FROM DailyPrices 
     WHERE dpTicker = 'GLE.PA' 
     AND dpDate = 
     (SELECT min(dpDate) 
     FROM DailyPrices 
     WHERE strftime('%Y%m', dpDate) = '201509' 
     ) 
    ) AS Open, 
    max(dpHigh) AS High, 
    min (dpLow) AS Low, 
    (SELECT dpClose 
     FROM DailyPrices 
     WHERE dpTicker = 'GLE.PA' 
     AND dpDate = 
     (SELECT max(dpDate) 
     FROM DailyPrices 
     WHERE strftime('%Y%m', dpDate) = '201509' 
     ) 
    ) AS Close 
FROM DailyPrices 
WHERE dpTicker ='GLE.PA' 
AND strftime('%Y%m', dpDate) = '201509'; 

查詢的輸出如下:

bash-3.2$ sqlite3 myShares < month.sql 
month  Open  High  Low   Close  
---------- ---------- ---------- ---------- ---------- 
2015-09  42.72  44.07  37.25  39.85  
bash-3.2$ 

用下面的查詢我設法爲高和低產生月度總覽:

SELECT 
    strftime('%Y-%m', dpDate) AS Month, 
    max(dpHigh) AS High, 
    min(dpLow) AS Low 
FROM DailyPrices 
WHERE dpTicker ='GLE.PA' 
GROUP BY strftime('%Y%m', update); 

輸出的快照看起來如下:

bash-3.2$ sqlite3 myShares < monthly.sql 
Month  High  Low  
---------- ---------- ---------- 
2000-01  219.32  184.346 
2000-02  206.43  181.977 
2000-03  210.411  181.503 
2000-04  221.405  197.805 
2000-05  226.239  55.9199 
... 

用下面的查詢,我設法提取正確打開並通過類比正確關閉數據:

SELECT 
    strftime('%Y-%m', dpDate) AS Month, 
    dpOpen AS Open 
FROM DailyPrices 
WHERE dpTicker = 'GLE.PA' 
AND dpDate IN 
    (SELECT min(dpDate) 
     FROM DailyPrices 
     WHERE dpTicker = 'GLE.PA' 
     GROUP BY strftime('%Y%m', dpDate) 
    ); 

輸出的快照如下:

bash-3.2$ sqlite3 myShares < Open.sql 
Month  Open  
---------- ---------- 
2000-01  218.846 
2000-02  200.269 
2000-03  206.525 
2000-04  201.312 
2000-05  215.908 
... 

我奮力查詢,month.sql和open.sql合併成一個查詢來獲取以下的輸出:

Month Open High Low Close 
------- ----- ----- ----- ----- 
2015-01 42.79 42.79 33.69 35.18 
2015-02 35.39 35.46 26.61 32.42 
2015-03 32.32 37.65 31.93 32.48 
... 

任何幫助解決這個問題將不勝感激。 問候

+0

所以,你要第一個查詢,但所有月份? –

+0

是的,這是正確的。 –

回答

1

有三個地方,第一個查詢是指特定月份搜索。讓我們刪除子查詢中的兩個事件;這需要使用別名,使我們可以通過名稱指的是同一個表的其他實例:

SELECT 
    strftime ('%Y-%m', dpDate) AS month,  
    (SELECT dpOpen 
     FROM DailyPrices 
     WHERE dpTicker = 'GLE.PA' 
     AND dpDate = 
     (SELECT min(dpDate) 
     FROM DailyPrices AS DP2 
     WHERE strftime('%Y%m', DP2.dpDate) = strftime('%Y%m', DP1.dpDate) 
     ) 
    ) AS Open, 
    max(dpHigh) AS High, 
    min (dpLow) AS Low, 
    (SELECT dpClose 
     FROM DailyPrices 
     WHERE dpTicker = 'GLE.PA' 
     AND dpDate = 
     (SELECT max(dpDate) 
     FROM DailyPrices AS DP2 
     WHERE strftime('%Y%m', DP2.dpDate) = strftime('%Y%m', DP1.dpDate) 
     ) 
    ) AS Close 
FROM DailyPrices AS DP1 
WHERE dpTicker ='GLE.PA' 
AND strftime('%Y%m', dpDate) = '201509'; 

現在,只有最外層的查詢需要知道的一個月,我們可以簡單地用GROUP更換濾芯BY:

SELECT 
    strftime ('%Y-%m', dpDate) AS month,  
    (...) AS Open, 
    max(dpHigh) AS High, 
    min (dpLow) AS Low, 
    (...) AS Close 
FROM DailyPrices 
WHERE dpTicker ='GLE.PA' 
GROUP BY strftime('%Y%m', dpDate); 

請注意,開/關子查詢可以使用ORDER BY/LIMIT被簡化:

(SELECT dpOpen 
FROM DailyPrices 
WHERE dpTicker = 'GLE.PA' 
    AND ... dpDate ... 
ORDER BY dpDate ASC 
LIMIT 1) AS Open 
0

謝謝CL!對於一個SQLite新手來說,這是一個很好的學習,尤其是對於ALIASES的使用。

您的建議產生總體良好的結果,但是,跑了幾個測試運行時,我注意到的以下樣式偶然的錯誤:

bash-3.2$ sqlite3 myShares < tst.sql 
month  Open  High  Low   Close  
---------- ---------- ---------- ---------- ---------- 
2006-03  75.4675  76.5852  70.4136  74.4956 
2006-04  75.0787  75.9048  70.5108  72.7948 
2006-05     77.0225  68.5184  70.7538 
2006-06  70.5594  73.4751  64.7767  72.7462 
2006-07  72.5518  75.2245  68.2269  74.0582 
bash-3.2$ 

正如你所看到的公開價格爲2006年5月不見了。我覈實,實際存在數據:

bash-3.2$ sqlite3 myShares < test.sql 
dpTicker dpDate  dpOpen  dpHigh  dpLow  dpClose  dpVolume dpAdjClose dpCreated   dpModified   
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ------------------- ------------------- 
BNP.PA  2006-04-26 72.0173  73.1835  72.0173  72.892  2623400  48.8861  2015-12-08 12:04:22 2015-12-08 12:04:22 
BNP.PA  2006-04-27 73.8153  74.0096  72.5032  73.6209  6001400  49.375  2015-12-08 12:04:22 2015-12-08 12:04:22 
BNP.PA  2006-04-28 73.4751  73.9611  72.6976  72.7948  4133300  48.8209  2015-12-08 12:04:22 2015-12-08 12:04:22 
BNP.PA  2006-05-02 72.5518  73.5723  72.3574  73.2807  3085400  49.1468  2015-12-08 12:04:22 2015-12-08 12:04:22 
BNP.PA  2006-05-03 73.8639  74.0096  72.5518  72.649  3290400  48.7231  2015-12-08 12:04:22 2015-12-08 12:04:22 
BNP.PA  2006-05-04 72.892  73.5237  72.2602  73.3779  3640300  49.212  2015-12-08 12:04:22 2015-12-08 12:04:22 
BNP.PA  2006-05-05 73.6209  74.8357  73.4751  74.7872  3255600  50.1572  2015-12-08 12:04:22 2015-12-08 12:04:22 
bash-3.2$ 

對於每一個在SQLite數據庫的行情中,我通常這些錯誤的大約4在16年的時間。

只要我的SQLite新手知識達到,表中的數據是好的。

任何想法爲什麼偶爾查詢會跳轉一個摘要記錄?通常情況下,公開價格會出現下降,但不時會出現在收盤價格上。

最好的問候,

GAM

爲了記錄在案,下面是查詢我已經執行

SELECT 
    strftime ('%Y-%m', dpDate) AS month,  
    (SELECT dpOpen 
    FROM DailyPrices 
    WHERE dpTicker = 'BNP.PA' 
     AND dpDate = 
     (SELECT min(dpDate) 
     FROM DailyPrices AS DP2 
     WHERE strftime('%Y%m', DP2.dpDate) = strftime('%Y%m', DP1.dpDate) 
     ) 
    ORDER BY dpDate ASC 
    LIMIT 1) AS Open, 
    max(dpHigh) AS High, 
    min (dpLow) AS Low, 
    (SELECT dpClose 
     FROM DailyPrices 
     WHERE dpTicker = 'BNP.PA' 
     AND dpDate = 
     (SELECT max(dpDate) 
     FROM DailyPrices AS DP2 
     WHERE strftime('%Y%m', DP2.dpDate) = strftime('%Y%m', DP1.dpDate) 
     ) 
    ) AS Close 
FROM DailyPrices AS DP1 
WHERE dpTicker ='BNP.PA' 
AND strftime('%Y-%m', dpDate) > '2006-02' 
AND strftime('%Y-%m', dpDate) < '2006-08' 
GROUP BY strftime('%Y-%m', dpDate); 
+0

改進了SELECT dpOpen和dpClose: –

+0

(SELECT dpClose FROM DailyPrices WHERE dpTicker = 'GLE.PA' AND dpDate = (SELECT MAX(dpDate) FROM DailyPrices AS DP2 WHERE dpTicker = 'GLE.PA' \t \t AND strftime('%Y%m',DP2.dpDate)= strftime('%Y%m',DP1.dpDate) ) )AS Close –