我有一个表,其中包含一些数据和时间段,即开始日期和结束日期
------------------------------
| id | start_date | end_date |
|------------------------------|
| 0 | 1-1-2019 | 3-1-2019 |
|------------------------------|
| 1 | 6-1-2019 | 8-1-2019 |
|------------------------------|
我想运行一个查询,该查询将返回ID和这些时间段内的所有日期。例如,上表的查询结果将是:
------------------
| id | date |
|------------------|
| 0 | 1-1-2019 |
|------------------|
| 0 | 2-1-2019 |
|------------------|
| 0 | 3-1-2019 |
|------------------|
| 1 | 6-1-2019 |
|------------------|
| 1 | 7-1-2019 |
|------------------|
| 1 | 8-1-2019 |
------------------
我正在使用Redshift,因此我需要Postgres支持它,并考虑this
将极大地帮助您
答案 0 :(得分:0)
这个问题最初被标记为Postgres。
使用generate_series()
:
select t.id, gs.dte
from t cross join lateral
generate_series(t.start_date, t.end_date, interval '1 day') as gs(dte);
答案 1 :(得分:0)
常用的方法是创建带有日期列表的日历表。实际上,日历表可以扩展为包括以下列:
只需在Excel中创建表格,另存为CSV,然后COPY
将其放入Redshift。
然后您可以JOIN
到表中,例如:
SELECT
table.id,
calendar.date
FROM table
JOIN calendar
WHERE
calendar.date BETWEEN table.start_date AND table.end_date
答案 2 :(得分:0)
好的,我花了一段时间才到达那里,但这是我所做的(尽管并不为此而感到骄傲): 我创建了一个查询,该查询生成了过去6年的日历,将其与我的表交叉连接,然后从我的日历表中选择了相关日期。
WITH
days AS (select 0 as num UNION select 1 as num UNION select 2 UNION select 3 UNION select 4 UNION select 5 UNION select 6 UNION select 7 UNION select 8 UNION select 9 UNION select 10 UNION select 11 UNION select 12 UNION select 13 UNION select 14 UNION select 15 UNION select 16 UNION select 17 UNION select 18 UNION select 19 UNION select 20 UNION select 21 UNION select 22 UNION select 23 UNION select 24 UNION select 25 UNION select 26 UNION select 27 UNION select 28 UNION select 29 UNION select 30 UNION select 31),
month AS (select num from days where num <= 12),
years AS (select num from days where num <= 6),
rightnow AS (select CAST( TO_CHAR(GETDATE(), 'yyyy-mm-dd hh24') || ':' || trim(TO_CHAR((ROUND((DATEPART (MINUTE, GETDATE()) / 5), 1) * 5 ),'09')) AS TIMESTAMP) as start),
calendar as
(
select
DATEADD(years, -y.num, DATEADD( month, -m.num, DATEADD( days, -d.num, n.start ) ) ) AS period_date
from days d, month m, years y, rightnow n
)
select u.id, calendar.period_date
from periods u
cross join calendar
where date_part(DAY, u.finishedat) >= date_part(DAY, u.startedat) + 1 and date_part(DAY, calendar.period_date) < date_part(DAY, u.finishedat) and date_part(DAY, calendar.period_date) > date_part(DAY, u.startedat) and calendar.period_date < u.finishedat and calendar.period_date > u.startedat