Redshift中generate_series()函数调用失败问题求助
解决Redshift中生成日期序列并插入的报错问题
问题原因
Redshift的generate_series函数与标准PostgreSQL(DBeaver默认适配的数据库类型)行为不同:
- 要求时间间隔参数必须显式声明为
INTERVAL类型,不能直接传入字符串; - 原SQL中
to_timestamp的格式符与输入日期字符串不匹配(用了yyyy/mm/dd但输入是yyyy-mm-dd); - 存在语法错误:
as. day_of_week多了一个多余的点。
解决方案一:修正generate_series参数类型与格式
调整参数类型转换,修正语法错误,适配Redshift要求:
INSERT INTO table_dates(calendar_date, day_of_week) SELECT generate_series::date as calendar_date, TO_CHAR(generate_series, 'Dy') as day_of_week FROM generate_series( CAST('1990-01-01' AS TIMESTAMP WITH TIME ZONE), CAST('2050-12-31' AS TIMESTAMP WITH TIME ZONE), INTERVAL '1 day' );
解决方案二:基于数字序列生成日期(Redshift更稳定的方式)
如果第一种方法仍有兼容性问题,推荐用系统表生成数字序列再转换为日期,这种方式在Redshift中更可靠:
INSERT INTO table_dates(calendar_date, day_of_week) SELECT DATEADD(day, rn, '1989-12-31') AS calendar_date, TO_CHAR(DATEADD(day, rn, '1989-12-31'), 'Dy') AS day_of_week FROM ( -- 生成从0到总天数的数字序列 SELECT ROW_NUMBER() OVER () - 1 AS rn FROM SVV_STATISTICS -- 计算1990-01-01到2050-12-31的总天数+1 LIMIT (DATEDIFF(day, '1990-01-01', '2050-12-31') + 1) ) AS numbers;
说明
- 两种方法都能生成1990-01-01到2050-12-31的所有日期及对应的星期缩写(如Mon、Tue);
- 方案二利用Redshift系统表
SVV_STATISTICS生成足够多的行,避免generate_series的类型限制,适合大跨度日期生成。
内容的提问来源于stack exchange,提问作者Joyce
相关产品推荐
相关产品推荐

