2014-11-05 41 views
1

所以我用這個SQL得到大量數據從服務器:SQL:只取得來自大型數據集的採樣數據

SELECT value,DATE_FORMAT(`time`,'%Y-%m-%dT%H:%i:%sZ') AS `time` 
    FROM history WHERE :id=reference AND 
    (time BETWEEN :start AND :end) ORDER BY time LIMIT 100 "; 

限制設置爲固定的100個條目。

但是在給定的時間範圍內可能有5 000個條目。

這是我的目標:我想按照每個條目之間的時間對這些條目進行抽樣。 因此,例如,每個條目之間的間隔時間爲60秒(假設它是參數),那麼我將收到100個條目(從5000),但每個條目之間總會有一分鐘的差異。

E.g.

value1,14:40:40 
value2,14:41:40 
... 
value100,16:20:40 

這是可以通過SQL嗎?還是我必須通過PHP解析這些大數據?

如果它不適用於SQL,那麼是否有可能讓這100個條目在這5000個條目中均勻分佈? (所以不是時間,但我會得到固定條目id1,id50,id100,id150,...,id5000)。再次只是與SQL。

謝謝!

回答

2

就像Kristof在他的回答中所說的那樣:排列行並通過應用行號來獲取每個第n行。這是它是如何在MySQL做:

select 
    rows.value, 
    date_format(rows.`time`,'%Y-%m-%dT%H:%i:%sZ') AS `time` 
from 
(
    select 
    @row_number := @row_number + 1 as row_number, 
    history.* 
    from history 
    cross join (select @row_number := 0) as t 
    where reference = :id and `time` between :start and :end 
    order by `time` 
) as rows 
cross join 
(
    select count(*) as cnt 
    from history 
    where reference = :id and `time` between :start and :end 
) as rowcount 
where mod(rows.row_number - 1, ceil(rowcount.cnt/100)) = 0; 

這是怎麼了同樣的情況也看在另一個DBMS,甲骨文例如,使用分析功能:

select 
    rows.value, 
    to_char(rows."time",'yyyy-mm-dd hh24:mi:ss') AS "time" 
from 
( 
    select 
    row_number() over (order by "time") as rown, 
    count(*) over() as cnt, 
    history.* 
    from history 
    where reference = :id and "time" between :start and :end 
) rows 
where mod(rows.rown - 1, ceil(rows.cnt/100)) = 0; 

這些查詢導致100個記錄或少一點,這取決於表格中包含的行數。您也可以在MySQL中使用TRUNCATE(rowcount.cnt,0)而不是CEIL(rowcount.cnt),因此可以獲得100行或更多,並且還可以使用LIMIT 100來獲取完全100行(假設表中至少有100行)。

+0

謝謝你們,你是最棒的 – user1762087 2014-11-05 17:30:08

0

你可以選擇rowNumber並計算該rowNumber的模數。 不知道如何,將在MySQL,但T-SQL來完成是這樣的:

SELECT ROW_NUMBER() over(order by idField) % 50 as selector, * 
FROM history 
WHERE selector = 1 

這將計算行數和重置計數器每50記錄,給你一個攤開的結果。

+0

也謝謝你:-) – user1762087 2014-11-05 17:30:32