SQL获取时间戳范围内的项目,然后关闭项目

时间:2016-12-30 17:57:30

标签: sql postgresql

我有下表(项目)

iteminfo, timestamp_start, timestamp_stop

我需要根据时间戳选择一个项目:

SELECT * 
FROM items 
WHERE timestamp_start <= '2016-12-27T03:00:00' 
  AND timestamp_stop >= '2016-12-27T04:00:00'

现在我还需要获取下一个最接近的项目(即timestamp_start大于所选项目的timestamp_stop

3 个答案:

答案 0 :(得分:1)

您可以使用row_number执行此操作(获取下一个项目)。我已将其作为CTE进行分解以明确说明,但这些可以合并为子查询。

WITH item_rn AS
(  -- add a row number based on what we care about getting next (timestamp_start)
  SELECT *, 
        ROW_NUMBER() OVER (ORDER BY timestamp_start) as RN
  FROM items 
), list_in_range AS
( -- get our base list
  SELECT *
  FROM item_rn
  WHERE timestamp_start <= '2016-12-27T03:00:00' AND timestamp_stop >= '2016-12-27T04:00:00'
), next_item AS
( -- get the next item
  SELECT *
  FROM item_rn
  WHERE rn = (SELECT MAX(rn) FROM list_in_range) + 1
) -- combine lists for final result.
SELECT *
FROM list_in_range

UNION ALL

SELECT *
FROM next_item

答案 1 :(得分:0)

我不确定“下一个最接近的项目”是什么意思。如果您想要下一个项目的ID,请使用lead()

SELECT i.*
FROM (SELECT i.*, LEAD(i.item_id) OVER (ORDER BY timestamp_start) as next_item_id
      FROM items i
     ) i
WHERE timestamp_start <= '2016-12-27T03:00:00' AND
      timestamp_stop >= '2016-12-27T04:00:00';

作为注释:您可以通过引用表来获取整个记录:

SELECT i.*
FROM (SELECT i.*, LEAD(i) OVER (ORDER BY timestamp_start) as next_item
      FROM items i
     ) i
WHERE timestamp_start <= '2016-12-27T03:00:00' AND
      timestamp_stop >= '2016-12-27T04:00:00';

使用表别名来引用行通常会让人感到困惑,除非你在Postgres中非常先进,所以我更愿意用独特的ID来思考。

答案 2 :(得分:-1)

我想我找到了一个直截了当的解决方案:

SELECT *
        FROM items 
        WHERE timestamp_start <= '2016-12-27T04:00:00' 
          AND timestamp_stop >= '2016-12-27T04:00:00'
UNION
SELECT *
        FROM items 
        WHERE timestamp_start> '2016-12-27T04:00:00'
ORDER BY timestamp_start LIMIT 2