2017-08-16 17 views
0

我有一個DB有三個字段的表格:id,valuetimestamp在postgres中,我如何在一個範圍內找到記錄,然後在兩側範圍內找到單個記錄?

給定兩個日期,我知道如何在postgres中編寫查詢,使用timestamp字段將查找範圍內的所有記錄。麻煩的是,我也想在的範圍之前找到最近的單個記錄,並且在之後的範圍內找到單個最接近的記錄

所以,如果我有這個表:

id | value | timestamp 
---+-------+--------------------- 
1 |  18| Jan, 1 2017, 09:00:000 
2 |  16| Jan, 1 2017, 09:05:000 
3 |  14| Jan, 1 2017, 09:21:150 
4 |  12| Jan, 1 2017, 10:01:150 
5 |  13| Jan, 1 2017, 10:07:000 
6 |  09| Jan, 1 2017, 10:23:000 

我想寫一個查詢,需要在時代: Jan, 1 2017, 9:10:000直到Jan, 1 2017, 10:05:000

將返回:

id | value | timestamp 
---+-------+--------------------- 
2 |  16| Jan, 1 2017, 09:05:000 
3 |  14| Jan, 1 2017, 09:21:150 
4 |  12| Jan, 1 2017, 10:01:150 
5 |  13| Jan, 1 2017, 10:07:000 

id 2,是距離範圍底部最近的記錄,但仍小於範圍的底部。 id 5是距離範圍頂部最近的記錄,但仍大於(或等於)該範圍的頂部。

回答

2

使用三個工會做到這一點:

select * from table where timestamp between start_ts and end_ts 
union all 
(select * from table where timestamp < start_ts order by timestamp desc limit 1) 
union all 
(select * from table where timestamp > end_ts order by timestamp limit 1) 

這些子查詢的所有都符合上timestamp列的索引。

0

我建議你UNION

WITH cte as (
     SELECT * 
     FROM YourTable 
     WHERE timestamp BETWEEN @start AND @end 
), nearStart as (
     SELECT * 
     FROM YourTable 
     WHERE id = (SELECT Max(id) 
        FROM YourTable 
        WHERE id < (SELECT MIN(ID) FROM cte)) 
), nearEnd as (
     SELECT * 
     FROM YourTable 
     WHERE id = (SELECT MIN(id) 
        FROM YourTable 
        WHERE id > (SELECT MAX(ID) FROM cte)) 
) 
SELECT * FROM cte 
UNION ALL 
SELECT * FROM nearStart 
UNION ALL 
SELECT * FROM nearEnd 
+0

胡安,你的答案太複雜了。並且它假定id-s與時間戳 –

+0

@DanielVidić的順序相同這裏沒有什麼複雜的,但是abelisto的答案更簡單。如果id沒有順序,您可以更改時間戳的id,但是應該爲timestamp添加一個索引 –

相關問題