我想在redshift中使用generate系列函数,但还没有成功。
红移文档说它不受支持。以下代码确实有效:
select *
from generate_series(1,10,1)
输出:
1
2
3
...
10
我想对日期做同样的事情。我尝试过多种变体,包括:
select *
from generate_series(date('2008-10-01'),date('2008-10-10 00:00:00'),1)
踢出去:
ERROR: function generate_series(date, date, integer) does not exist
Hint: No function matches the given name and argument types.
You may need to add explicit type casts. [SQL State=42883]
也尝试过:
select *
from generate_series('2008-10-01 00:00:00'::timestamp,
'2008-10-10 00:00:00'::timestamp,'1 day')
并尝试过:
select *
from generate_series(cast('2008-10-01 00:00:00' as datetime),
cast('2008-10-10 00:00:00' as datetime),'1 day')
两个人都踢了出来:
ERROR: function generate_series(timestamp without time zone, timestamp without time zone, "unknown") does not exist
Hint: No function matches the given name and argument types.
You may need to add explicit type casts. [SQL State=42883]
如果看起来不像我将使用其他帖子中的代码:
SELECT to_char(DATE '2008-01-01'
+ (interval '1 month' * generate_series(0,57)), 'YYYY-MM-DD') AS ym
答案 0 :(得分:17)
亚马逊Redshift seems to be based on PostgreSQL 8.0.2。 generate_series()的时间戳参数在8.4中添加。
这样的东西可以回避这个问题,可能在Redshift中工作。
SELECT current_date + (n || ' days')::interval
from generate_series (1, 30) n
它适用于PostgreSQL 8.3,这是我可以测试的最早版本。它记录在8.0.26中。
稍后。 。 强>
似乎Redshift中的generate_series() is unsupported。但鉴于您已经确认select * from generate_series(1,10,1)
有效,上述语法至少可以为您提供战斗机会。 (虽然间隔数据类型也记录为在Redshift上不受支持。)
还是晚些时候。 。 强>
您还可以创建一个整数表。
create table integers (
n integer primary key
);
随意填充它。您可以在本地使用generate_series(),转储表并在Redshift上加载它。 (我不知道;我不使用Redshift。)
无论如何,您可以使用该表进行简单的日期算术,而无需直接引用generate_series()或间隔数据类型。
select (current_date + n)
from integers
where n < 31;
至少在8.3中有效。
答案 1 :(得分:12)
今天使用Redshift,您可以使用日期时间功能生成一系列日期,并输入数字表格。
select (getdate()::date - generate_series)::date from generate_series(1,30,1)
为我生成这个
date
2015-11-06
2015-11-05
2015-11-04
2015-11-03
2015-11-02
2015-11-01
2015-10-31
2015-10-30
2015-10-29
2015-10-28
2015-10-27
2015-10-26
2015-10-25
2015-10-24
2015-10-23
2015-10-22
2015-10-21
2015-10-20
2015-10-19
2015-10-18
2015-10-17
2015-10-16
2015-10-15
2015-10-14
2015-10-13
2015-10-12
2015-10-11
2015-10-10
2015-10-09
2015-10-08
答案 2 :(得分:6)
Redshift不完全支持generate_series()
功能。请参阅开发者指南的Unsupported PostgreSQL functions部分。
<强>更新强>
generate_series现在正在使用Redshift。
SELECT CURRENT_DATE::TIMESTAMP - (i * interval '1 day') as date_datetime
FROM generate_series(1,31) i
ORDER BY 1
这将生成最近30天的日期
答案 3 :(得分:0)
我需要做类似的事情,但是在7天内间隔5分钟。所以这是一个基于CTE的黑客(丑陋但不太冗长)
INSERT INTO five_min_periods
WITH
periods 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),
hours AS (select num from periods UNION ALL select num + 12 from periods),
days AS (select num from periods 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)
select
ROW_NUMBER() OVER(ORDER BY d.num DESC, h.num DESC, p.num DESC) as idx
, DATEADD(minutes, -p.num * 5, DATEADD( hours, -h.num, DATEADD( days, -d.num, n.start ) ) ) AS period_date
from days d, hours h, periods p, rightnow n
应该能够将此扩展到其他生成方案。这里的技巧是使用笛卡尔积连接(即没有JOIN / WHERE子句)来乘以手工制作的CTE以产生必要的增量并应用于锚定日期。
答案 4 :(得分:0)
根据@Ryan Tuck和@Slobodan Pejic generate_series()
的注释,在连接到另一个表时不适用于Redshift。
我使用的解决方法是在查询中写出系列中的每个值:
SELECT
'2019-01-01'::date AS date_month
UNION ALL
SELECT
'2019-02-01'::date AS date_month
使用这样的Python函数:
import arrow
def generate_date_series(start, end):
start = arrow.get(start)
end = arrow.get(end)
months = list(
f"SELECT '{month.format('YYYY-MM-DD')}'::date AS date_month"
for month in arrow.Arrow.range('month', start, end)
)
return "\nUNION ALL\n".join(months)