给出一个包含以下行的表:
+----+-------------------------+------------------------+
| ID | StartDate | EndDate |
+----+-------------------------+------------------------+
| 1 | 2016-02-05 20:00:00.000 | 2016-02-07 5:00:00.000 |
+----+-------------------------+------------------------+
我想制作一个这样的表:
+----+------------+----------+
| ID | Date | Duration |
+----+------------+----------+
| 1 | 2016-02-05 | 4 |
| 1 | 2016-02-06 | 24 |
| 1 | 2016-02-07 | 5 |
+----+------------+----------+
这是一个面试风格的问题。我想知道如何解决这个问题。是否可以使用标准的SQL查询语法来完成此操作?或者像pl / pgSQL这样的过程语言需要像这样进行查询吗?
答案 0 :(得分:0)
基本理念是:
SELECT date_trunc('day', dayhour) as dd,count(*)
FROM (VALUES (1, '2016-02-05 20:00:00.000'::timestamp, '2016-02-07 5:00:00.000'::timestamp)
) v(ID, StartDate, EndDate), lateral
generate_series(StartDate, EndDate, interval '1 hour') g(dayhour)
GROUP BY dd
ORDER BY dd;
这会增加一个小时,所以这更准确:
SELECT date_trunc('day', dayhour) as dd,count(*)
FROM (VALUES (1, '2016-02-05 20:00:00.000'::timestamp, '2016-02-07 5:00:00.000'::timestamp)
) v(ID, StartDate, EndDate), lateral
generate_series(StartDate, EndDate - interval '1 hour', interval '1 hour') g(dayhour)
GROUP BY dd
ORDER BY dd;
从技术上讲,不需要lateral
(在这种情况下,我会将逗号替换为cross join
)。但是,这是横向连接的一个例子,因此明确是好的。
我还应该注意,以上是最简单的方法。但是,group by
会降低查询速度。还有其他方法不需要每小时生成一个系列。