2014-01-30 111 views
0

我有一個查詢按時間執行聚合記錄,但我有一些錯誤。按時間彙總記錄

我的情況:我的股票行情數據每分鐘5.6一個創紀錄的0900存儲在MySQL數據庫VERS高達1730,這是511點的記錄每天

enter image description here

我需要彙總這些數據進行不同的時間幀,讓我們假設5分鐘,使得

volume5min - >總和體積0900:0904

open5min - 爲0900記錄(在範圍內首開值)

close5min>開值 - >最高每日0900時至價值 - 0904記錄(在範圍內最後收盤值)

high5min>收盤值0904範圍

low5min - >最低在0900的值0904範圍

等。

我有一個查詢做到這一點,但我得到的開啓和關閉聚合值誤差

SELECT 
    floor(cast(time as SIGNED)/5) as timeInterval, 
    date, 
    time, 
    MAX(high) AS high, 
    MIN(low) as low, 
    SUM(volume) as volume, 
    (select 
      open 
     from 
      atlantia a2 
     where 
      a1.time = a2.time 
     order by time 
     limit 1) as open, 
    (select 
      close 
     from 
      atlantia a2 
     where 
      a1.time = a2.time 
     order by time desc 
     limit 1) as close 
FROM 
    atlantia a1 
GROUP BY date , timeInterval 

這是我得到執行查詢

enter image description here

打開和關閉是沒有正確彙總,而其他列看起來不錯。

更重要的是,改變總的時間框架,我得到不正確的時間,如下面

enter image description here

從9時開始的60分鐘的例子,我應該有1000,1100等,而現在我也有1020,1140等

列類型有:

日期:CHAR 時間:CHAR 其餘全部爲雙卷卻是INTEGER。

如何修改此查詢以正確彙總值?

編輯:,以驗證您的最後一個查詢,我已經手動檢查任何一個小時,這些都是正確的價值觀,我應該得到

enter image description here

查詢返回的密切價值觀的差異,所有其餘它的確定

enter image description here

關閉值應爲時限的最後一個記錄,即時間betwee n 0900和0959 close是緊密列中的0959值。

編輯2:看來我發現其中的訣竅是,現在有了這個查詢這一切工作正常

SELECT 
Sub1.timeInterval, 
a1.date, 
MIN(a1.time), 
MAX(a1.high) AS high, 
MIN(a1.low) as low, 
SUM(a1.volume) as volume, 
a2.open as open, 
a3.close as close 
FROM atlantia a1 
INNER JOIN 
(
SELECT floor((cast(SUBSTRING(time,1,2) AS SIGNED) * 60 + cast(SUBSTRING(time,3,2) AS SIGNED)) /60) AS timeInterval, MIN(time) AS minTime, MAX(time) AS maxtime 
FROM atlantia 
GROUP BY timeInterval 
) Sub1 
ON floor((cast(SUBSTRING(a1.time,1,2) AS SIGNED) * 60 + cast(SUBSTRING(a1.time,3,2) AS SIGNED)) /60) = Sub1.timeInterval 
INNER JOIN atlantia a2 ON a2.time = Sub1.minTime AND a1.date = a2.date 
INNER JOIN atlantia a3 ON a3.time = Sub1.maxtime AND a1.date = a3.date 
GROUP BY a1.date , timeInterval 

如果我想在不同的時間框架聚集,即5分鐘?我只是用/ 5更換兩個/ 60?

謝謝

+0

我最後的查詢工作正常60分鐘,也是5分鐘,10分鐘等等。對於奇數時間幀劃分有聚集問題,例如7或11分鐘。任何有關如何解決真正讚賞的建議。感謝 –

回答

1

我可以發現幾個問題。

您正在將時間存儲在字符字段中,並且在將10:20點鐘的符號進行投射時,將視爲1020而不是10 * 60分鐘+20分鐘。因此,當除以60時,10:00是16,而10:20是17,因此在你的代碼中它們有2個不同的時間間隔。

另一個問題是您已將時間作爲字段返回,而未在GROUP BY子句中指定它。它返回的時間值來自未確定的行(通常是第一個,但並非總是)。可能最容易指定MIN(時間)。

SELECT 
    floor((cast(SUBSTRING(time,1,2) AS SIGNED) * 60 + cast(SUBSTRING(time,3,2) AS SIGNED)) /60) AS timeInterval, 
    date, 
    MIN(time), 
    MAX(high) AS high, 
    MIN(low) as low, 
    SUM(volume) as volume, 
    (select 
      open 
     from 
      atlantia a2 
     where 
      a1.time = a2.time 
     order by time 
     limit 1) as open, 
    (select 
      close 
     from 
      atlantia a2 
     where 
      a1.time = a2.time 
     order by time desc 
     limit 1) as close 
FROM 
    atlantia a1 
GROUP BY date , timeInterval 

可能會清理sql以刪除子查詢。

編輯

了發揮,這可能做到這一點,但不知道效率和不表,我不能測試: -

SELECT 
    Sub1.timeInterval, 
    a1.date, 
    MIN(a1.time), 
    MAX(a1.high) AS high, 
    MIN(a1.low) as low, 
    SUM(a1.volume) as volume, 
    MIN(a2.open) as open, 
    MIN(a3.close) as close 
FROM atlantia a1 
INNER JOIN 
(
    SELECT floor((cast(SUBSTRING(time,1,2) AS SIGNED) * 60 + cast(SUBSTRING(time,3,2) AS SIGNED)) /60) AS timeInterval, MIN(time) AS minTime, MAX(time) AS maxtime 
    FROM atlantia 
    GROUP BY timeInterval 
) Sub1 
ON floor((cast(SUBSTRING(a1.time,1,2) AS SIGNED) * 60 + cast(SUBSTRING(a1.time,3,2) AS SIGNED)) /60) = Sub1.timeInterval 
INNER JOIN atlantia a2 ON a2.time = Sub1.minTime AND a1.date = a2.date 
INNER JOIN atlantia a3 ON a3.time = Sub1.minTime AND a1.date = a3.date 
GROUP BY a1.date , timeInterval 
+0

@Kickstart ...感謝您的代碼修復了時間間隔問題,但仍然存在打開和關閉的錯誤值。 –

+0

認爲存在的問題是,您獲得的是與任何時間段開始時的時間匹配的任何行的打開和關閉值,但您並未檢查日期。我會玩一個更好的解決方案。 – Kickstart

+0

@Albertoacepsut - 快速玩 – Kickstart