[英]Select equally distant rows based on a timestamp column in MySQL
如何從表中選擇固定數量的行,其中時間戳列和返回行彼此相等。 我需要這些點作為樣本點來繪制時間序列。 我知道解決這個問題的其他技術,比如crossfilter等,但我現在想要能夠使用服務器。
例如,下表:(為簡化起見,簡化了時間戳)
id key val timestamp
1 'a' 100 1am
2 'b' 120 2am
3 'c' 130 3am
4 'd' 140 4am
5 'e' 130 5am
6 'f' 135 6am
7 'g' 136 7am
8 'h' 139 8am
9 'i' 149 9am
10 'j' 140 10am
11 'k' 140 11am
12 'l' 135 12pm
所以我希望能夠運行一個返回大小為3的樣本的查詢,它應該返回第1,5和9行。
我不想使用id,因為我的表比這更復雜,我將在where where子句等應用於我的查詢,因此使用ID不會起作用。
從使用其他RDBS我知道RANK,但它似乎不存在於mysql中,我看到了解決方法,就像這里的那個,但我認為這不是一個寫一個干凈的mysql方法。
有關如何解決這個問題的任何建議?
您可能需要一個步進功能來將時間戳映射到一組有限的“步驟”。 這可以在MySQL中表達如下:
--
-- `min_v` and `max_v` are respectively the first and last value value on the range
-- `samples` is the number of sample ("steps") expected
-- `value` is the actual value
--
CREATE FUNCTION step(min_v int, max_v int, samples int, value int)
RETURNS int DETERMINISTIC
RETURN min_v + (value - min_v) * (samples - 1) DIV (max_v-min_v)
為簡單起見,我在這里使用整數而不是時間戳。 您將在MySQL文檔中輕松找到如何從時間戳轉換為“unix epoch” 。
定義函數后,您只需在選擇查詢中按“步驟”分組,只保留每個步驟的第一個樣本:
select data.k, data.value FROM tbl AS data
join (select id, MIN(ts) FROM tbl GROUP BY step(1,12,4,ts) ) as s
on s.id = data.id;
有關實例,請參見http://sqlfiddle.com/#!2/d5ccb/3 。
用基本算術做這個。 如果您假設(如您的示例中)時間是精確的,並且您知道您想要的第一個時間戳以及它們之間的小時數:
select t.*
from t
where mod(TIME_TO_SEC(TIMEDIFF(t.timestamp, @FirstTimeStamp)), 60*60*@HourDIff) = 0;
要計算兩者之間的小時數,只需獲取最小和最大時間戳之間差異的整數部分:
select (TIME_TO_SEC(TIMEDIFF(max(t.timestamp), min(t.timestamp)) / @YOURCOUNT) as DiffSeconds;
此外,假設第一個時間戳是表中的第一個時間戳。
現在,讓我們把它們放在一起:
select t.*
from t cross join
(select min(timestamp) as FirstTimeStamp,
select (TIME_TO_SEC(TIMEDIFF(max(t.timestamp), min(t.timestamp)) / @YOURCOUNT) as DiffSeconds
from t
) const
where mod(TIME_TO_SEC(TIMEDIFF(t.timestamp, FirstTimeStamp)), DiffSeconds) = 0;
這確實假設您的時間戳完全准確。 如果這是一個問題,也許你應該使用id
代替。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.