根据下表,我想在00:00:00准确选择每个ID的值。如果在此确切时间有条目,则返回该条目,否则使用线性插值(00:00:00之前和之后的最近值之间的虚拟图线)进行计算。如果在给定时间之后没有值,则返回最后一个值,或者使用最后两个点的线性插值。
ID|Timestamp|Value
1|2015-01-01 23:00:00|90
1|2015-01-02 01:00:00|110
2|2015-01-01 23:00:00|210
2|2015-01-02 01:00:00|190
3|2015-01-02 00:00:00|50
4|2015-01-01 23:00:00|100
5|2015-01-01 22:00:00|80
5|2015-01-01 23:00:00|90
结果:
ID|Value
1|100
2|200
3|50
4|100
5|100
这仅适用于MySQL以及如何实现?
答案 0 :(得分:0)
首先,让我们将它分成单个条目,如#3与双条目(其余):
( SELECT ID, value FROM tbl GROUP BY ID HAVING COUNT(*) = 1 )
UNION ALL
( ... ) -- This needs interpolation code, below
ORDER BY ID;
分离这对行很棘手,因为没有好的方法可以做“groupwise-max”。所以,相反,我将使用@variables并按顺序遍历表。
要舍入到最近的午夜可能是ROUND(... / 86400) * 86400
。潜在的问题是你所在的time_zone。我不想解决这个问题。
SELECT ID, val FROM (
SELECT ID,
IF(ID != @prevID, '1st', '2nd') AS picker, -- See WHERE filter, below
@ts = timestamp, -- Need an INT here, not sure that is what I have
@dts = @ts - @prev_ts,
@dval = value - @prev_val,
@midnight := ROUND(@ts / 86400) * 86400, -- DST issues?
value + (@midnight - @ts) * (@dval / @dts) AS val, -- interpolate
@prev_id = ID,
@prev_ts = @ts,
@prev_val = value
FROM ( SELECT @prevID := 0 ) AS Initialize
JOIN tbl
ORDER BY ID, timestamp
) AS x
WHERE picker = '2nd'
ORDER BY ID
将该怪物作为UNION的第二部分。