我正在尝试编写一个查询,以便从简单日历应用的事件查询中检索数据。 表结构如下:
table name: events
Column | Type
---------+-----------
id | integer
start | timestamp
end | timestamp
表格内的数据
id| start | end
--+---------------------+--------------------
1 | 2017-09-01 12:00:00 | 2017-09-01 12:00:00
2 | 2017-09-03 10:00:00 | 2017-09-03 12:00:00
3 | 2017-09-08 12:00:00 | 2017-09-11 12:00:00
4 | 2017-09-11 12:00:00 | 2017-09-11 12:00:00
预期结果是
date | event.id
-----------+---------
2017-09-01 | 1
2017-09-03 | 2
2017-09-08 | 3
2017-09-09 | 3
2017-09-10 | 3
2017-09-11 | 3
2017-09-11 | 4
正如您所看到的,只检索有事件的天数(不仅仅是开始和结束,还有两天之间),根本没有检索到没有事件的日子。 在第二步中,我希望能够限制不同天数,例如“获得4天的活动”可能超过4行。
现在我只能使用以下查询基于开始日期检索事件:
SELECT start::date, id FROM events WHERE events.start::date >= '2017-09-01' LIMIT 3
认为我已经知道DENSE_RANK和generate_series,但到目前为止我还没有办法填补开始和结束之间的空白,但没有找到没有数据的日子。
简而言之: 我想得到的是:在接下来的X天举行活动。包含事件的日期是开始< = date> = end
的日期有什么想法吗?
感谢Tim我现在有以下查询(修改为使用generate_series而不是表,并使用dense_rank添加了限制):
select date, id FROM (
SELECT
DENSE_RANK() OVER (ORDER BY t1.date) as rank,
t1.date,
events.id
FROM
generate_series([DATE]::date, [DATE]::date + interval '365 day', '1 day') as t1
INNER JOIN
events
ON t1.date BETWEEN events.start::date AND events."end"::date
) as t
WHERE rank <= [LIMIT]
这项工作非常好,即使我对这种限制造成的性能影响不是100%肯定
答案 0 :(得分:2)
我认为您确实需要一个日历表来涵盖数据可能出现的所有日期。在下面的第一个CTE中,我生成了一个涵盖2017年9月份的表格。然后,我们需要做的就是内部加入此日历表,并在给定日期内出现的给定日期的标准事件表。
WITH cte AS (
SELECT CAST('2017-09-01' AS DATE) + (n || ' day')::INTERVAL AS date
FROM generate_series(0, 29) n
)
SELECT
t1.date,
t2.id
FROM cte t1
INNER JOIN events t2
ON t1.date BETWEEN CAST(t2.start AS DATE) AND CAST(t2.end AS DATE);
<强>输出:强>
date id
1 01.09.2017 00:00:00 1
2 03.09.2017 00:00:00 2
3 08.09.2017 00:00:00 3
4 09.09.2017 00:00:00 3
5 10.09.2017 00:00:00 3
6 11.09.2017 00:00:00 3
7 11.09.2017 00:00:00 4
在这里演示: