postgres中5分钟开始时间戳和结束时间戳之间的数据

时间:2016-01-04 10:28:54

标签: postgresql

我每隔5分钟检查一次开始时间戳和结束时间戳之间的数据但是没有按要求获得结果这是我的查询

CREATE TABLE table_1
(
  timestamp_col text
)

INSERT INTO table_1(
            timestamp_col)
    VALUES ('04-01-2016 10:00:00'),('04-01-2016 10:01:00'),('04-01-2016 10:02:00'),('04-01-2016 10:03:00')
    ,('04-01-2016 10:04:00'),('04-01-2016 10:05:00'),('04-01-2016 10:06:00'),('04-01-2016 10:07:00')
    ,('04-01-2016 10:08:00'),('04-01-2016 10:09:00'),('04-01-2016 10:00:00'),('04-01-2016 10:10:00')
    ,('04-01-2016 10:11:00'),('04-01-2016 10:12:00'),('04-01-2016 10:13:00'),('04-01-2016 10:14:00')
    ,('04-01-2016 10:15:00');

SELECT 
    to_timestamp(floor((extract('epoch' from timestamp_col::timestamp without time zone) / 300 )) * 300) 
    AT TIME ZONE 'UTC' as interval_alias
    FROM table_1 Where timestamp_col::timestamp without time zone
    Between '04-01-2016 10:02:00' AND '04-01-2016 10:15:00'
    GROUP BY interval_alias

2016-01-04 10:00:00
2016-01-04 10:05:00
2016-01-04 10:10:00
2016-01-04 10:15:00

必需输出

2016-01-04 10:02:00
2016-01-04 10:07:00
2016-01-04 10:12:00

假设我在" 04-01-2016 10:11:11"之间的第一个记录和" 04-01-2016 12:10:3​​0"是04-01-2016 10:12:11 我的间隔是5分钟然后应该显示时间戳的记录04-01-2016 10:12:11 + 5分钟,即04-01-2016 10:17:11如果有的话请帮助人们

1 个答案:

答案 0 :(得分:0)

您当前的声明正在将源数据规范化为5分钟,如果您删除查询的where部分,您会看到:

   interval_alias
---------------------
 2016-01-04 10:00:00
 2016-01-04 10:00:00
 2016-01-04 10:00:00
 2016-01-04 10:00:00
 2016-01-04 10:00:00
 2016-01-04 10:05:00
 2016-01-04 10:05:00
 2016-01-04 10:05:00
 2016-01-04 10:05:00
 2016-01-04 10:05:00
 2016-01-04 10:00:00
 2016-01-04 10:10:00
 2016-01-04 10:10:00
 2016-01-04 10:10:00
 2016-01-04 10:10:00
 2016-01-04 10:10:00
 2016-01-04 10:15:00

因此,这将增加额外的负载以及在查询的实际where部分之前销毁源数据。您需要在查询的where部分进行此计算。这样做的好处是只处理源数据的子集,并允许您仍然拥有原始的未修改数据。

您还需要计算从标准化值到所需起始值的偏移量。在这种情况下它只有120秒。所以硬编码(为了节省我的输入:))我们得到:

SELECT 
    timestamp_col 
    FROM table_1 Where timestamp_col::timestamp without time zone
    Between '04-01-2016 10:02:00' AND '04-01-2016 10:15:00'
    AND to_timestamp(floor(extract('epoch' from timestamp_col::timestamp without time zone))) = to_timestamp((floor(extract('epoch' from timestamp_col::timestamp without time zone) / 300 ) *300) +120)
    order by timestamp_col;

和结果:

    timestamp_col
---------------------
 04-01-2016 10:02:00
 04-01-2016 10:07:00
 04-01-2016 10:12:00
(3 rows)

包括偏移计算:

SELECT 
    timestamp_col 
    FROM table_1 Where timestamp_col::timestamp without time zone
    Between '04-01-2016 10:02:00' AND '04-01-2016 10:15:00'
    AND to_timestamp(floor(extract('epoch' from timestamp_col::timestamp without time zone))) = 
        to_timestamp((floor(extract('epoch' from timestamp_col::timestamp without time zone) / 300 ) *300) +
          floor(extract('epoch' from '04-01-2016 10:02:00'::timestamp without time zone)) - 
            (floor((extract('epoch' from '04-01-2016 10:02:00'::timestamp without time zone)) / 300) * 300)
        )
    order by timestamp_col;

偏移量只是距离最近的较旧标准化时间的秒数。所以10:02:00是10:00:00之后的2分钟(120秒)。

但我认为以下是一个更整洁的解决方案:

SELECT timestamp_col FROM table_1 
  WHERE timestamp_col::timestamp without time zone BETWEEN '04-01-2016 10:02:00' AND '04-01-2016 10:15:00'
  AND ABS((floor(extract('epoch' from '04-01-2016 10:02:00'::timestamp without time zone)) - 
    floor(extract('epoch' from timestamp_col::timestamp without time zone))))::integer % 300 = 0;

这将以秒为单位计算源数据中的开始时间和时间之间的差异,然后使用模运算符检查结果是否可以被300(5分钟)完全整除。无需计算偏移量,SQL(IMHO)更容易阅读。