我有一张表,其中包含一个流程的统计值。该表格式如下:
CREATE TABLE data (
process integer NOT NULL,
time timestamp NOT NULL
first double precision,
last double precision,
first_time timestamp,
last_time timestamp
)
此表中的数据每分钟插入一次,并包含聚合 最后一分钟的价值。例如,对于流程1,我们可以拥有 以下数据:
+---------------------------------------------------------------------------------+
| process | time | first | last | first_time | last_time |
+---------------------------------------------------------------------------------+
| 1 | 2014-09-22 12:00:00 | 100 | 200 | 2014-09-22 12:00:00 | 2014-09-22 12:00:59 |
| 1 | 2014-09-22 12:01:00 | 104 | 152 | 2014-09-22 12:01:00 | 2014-09-22 12:01:59 |
| 1 | 2014-09-22 12:02:00 | 141 | 155 | 2014-09-22 12:02:10 | 2014-09-22 12:02:59 |
| 1 | 2014-09-22 12:03:00 | 122 | 147 | 2014-09-22 12:03:00 | 2014-09-22 12:02:45 |
+---------------------------------------------------------------------------------+
正如您在第三行中所看到的,有时候第一个值不是 第二分钟。在最后一次这也发生了(第四行)。
使用this page中的第一个和最后一个函数以及date_round函数 从this page开始,我想在30中选择给定流程的第一个值 分钟间隔。
当我尝试以下两个查询时,结果都是正确的。
SELECT
date_round(time, '30 min'::interval) AS "time",
first(first)
FROM
data
WHERE
process = 1
AND
time > '2014-09-20 00:00:00'
AND
time < '2014-09-22 18:00:00'
GROUP BY 1
ORDER BY 1
和
SELECT
date_round(time, '30 min'::interval) AS "time",
first(first) AS "value"
FROM (
SELECT
time,
first
FROM
data
WHERE
process = 1
AND
time > '2014-09-20 00:00:00'
AND
time < '2014-09-22 18:00:00'
ORDER BY 1
) A
GROUP BY 1
ORDER BY 1
我的问题是:为什么第一个查询在这种情况下有效? postgres之前是否对数据进行排序 应用group by子句?
我怀疑是因为&#34;第一&#34; function返回两个传递参数的第一个值。 如果数据没有排序,那么第一次调用&#34;第一次&#34;集合函数 可以包含一个值不正确的值,导致值无效,对吗?
我可以安全地使用第一个查询吗?还是应该使用第二个查询?
答案 0 :(得分:2)
这是您真正想要的查询:
SELECT distinct on (date_round(time, '30 min'::interval))
date_round(time, '30 min'::interval) AS "time",
first
FROM data
WHERE process = 1 AND
time > '2014-09-20 00:00:00' AND
time < '2014-09-22 18:00:00'
ORDER BY date_round(time, '30 min'::interval), time;
Postgres没有在group by
之前进行排序 - 没有数据库通过SQL的定义来做。它恰好首先遇到最早的记录,但不能保证。事实上,我不认为第二个版本也可以保证订购(虽然我在这一点上找不到明确的Postgres文档)。