Amazon Redshift视图插入表时关联子查询模式不支持报错排查
问题:Amazon Redshift视图插入表时触发关联子查询不支持错误
我在使用Amazon Redshift时,尝试将视图中的数据插入到表中,执行如下语句:
INSERT INTO TABLE1 SELECT COL1, COL2, COL3, COL4 FROM VIEW1;
触发错误:
SQL Error [XX000]: ERROR: This type of correlated subquery pattern is not supported due to internal error
单独执行SELECT查询可以正常运行,且语法符合文档描述,想知道错误原因。
相关代码示例
视图创建语句
create or replace view schema1.tmp_v as with PP_WS_FLG as ( select YM, case mod(substring(YM,1,4),2) when 0 then 'Y1' else 'Y2' end as DISP_YEAR_JAN, case mod(to_char(add_months(to_date(YM,'YYYYMM'), -3),'YYYY'),2) when 0 then 'Y1' else 'Y2' end as DISP_YEAR_APR, substring(YM,5,6) as DISP_MON, substring(YM,1,4) || '/1 - ' || substring(YM,1,4) || '/12' as FILTER_1YEAR_JAN, to_char(add_months(to_date(YM,'YYYYMM'), -3),'YYYY') || '/4 - ' || to_char(add_months(to_date(YM,'YYYYMM'), + 9),'YYYY') || '/3' as FILTER_1YEAR_APR, case mod(substring(YM,1,4),2) when 0 then substring(YM,1,4) || '/1 - ' || (substring(YM,1,4) + 1) || '/12' else (substring(YM,1,4) -1) || '/1 - ' || substring(YM,1,4) || '/12' end as FILTER_2YEAR_JAN, case mod(to_char(add_months(to_date(YM,'YYYYMM'), -3),'YYYY'),2) when 0 then to_char(add_months(to_date(YM,'YYYYMM'), -3),'YYYY') || '/4 - ' || to_char(add_months(to_date(YM,'YYYYMM'), + 21),'YYYY') || '/3' else to_char(add_months(to_date(YM,'YYYYMM'), -15),'YYYY') || '/4 - ' || to_char(add_months(to_date(YM,'YYYYMM'), +9),'YYYY') || '/3' end as FILTER_2YEAR_APR, case when substring(YM,5,2) < 4 then 'Q1' when substring(YM,5,2) < 7 then 'Q2' when substring(YM,5,2) < 10 then 'Q3' else 'Q4' end as WS_DISP_QUARTER_JAN, case when substring(YM,5,2) < 4 then 'Q4' when substring(YM,5,2) < 7 then 'Q1' when substring(YM,5,2) < 10 then 'Q2' else 'Q3' end as WS_DISP_QUARTER_APR, case when substring(YM,5,2) < 7 then '1H' else '2H' end as WS_DISP_HALF_JAN, case when substring(YM,5,2) >= 4 and substring(YM,5,2) < 10 then '1H' else '2H' end as WS_DISP_HALF_APR, substring(YM,1,4) as WS_DISP_YEAR_JAN, to_char(add_months(to_date(YM,'YYYYMM'), -3),'YYYY') as WS_DISP_YEAR_APR, substring(YM,5,2) as WS_SORT_MONTH_JAN, to_char(add_months(to_date(YM,'YYYYMM'), -3),'MM') as WS_SORT_MONTH_APR from table1 ) select 1 demo from PP_WS_FLG;
目标表结构
create table schema2.tmp ( demo int );
触发错误的插入语句
insert into schema2.tmp select demo from schema1.tmp_v;
注:YM为YYYYMM格式的字符串。
错误原因
这是Redshift查询优化器的内部限制导致的:
- 单独执行
SELECT * FROM 视图时,优化器采用的执行计划逻辑相对简单,能正常解析视图内的CTE和复杂表达式。 - 但在
INSERT ... SELECT ...场景下,优化器会尝试重新规划执行计划,视图中CTE内嵌套的复杂日期函数、多分支CASE表达式组合,会被误识别为不支持的关联子查询模式,从而触发内部错误。
解决方法
1. 将视图逻辑内联到INSERT语句
绕过视图的执行计划限制,直接把视图中的CTE逻辑写到INSERT的SELECT部分:
insert into schema2.tmp with PP_WS_FLG as ( select YM, case mod(substring(YM,1,4),2) when 0 then 'Y1' else 'Y2' end as DISP_YEAR_JAN, case mod(to_char(add_months(to_date(YM,'YYYYMM'), -3),'YYYY'),2) when 0 then 'Y1' else 'Y2' end as DISP_YEAR_APR, substring(YM,5,6) as DISP_MON, substring(YM,1,4) || '/1 - ' || substring(YM,1,4) || '/12' as FILTER_1YEAR_JAN, to_char(add_months(to_date(YM,'YYYYMM'), -3),'YYYY') || '/4 - ' || to_char(add_months(to_date(YM,'YYYYMM'), + 9),'YYYY') || '/3' as FILTER_1YEAR_APR, case mod(substring(YM,1,4),2) when 0 then substring(YM,1,4) || '/1 - ' || (substring(YM,1,4) + 1) || '/12' else (substring(YM,1,4) -1) || '/1 - ' || substring(YM,1,4) || '/12' end as FILTER_2YEAR_JAN, case mod(to_char(add_months(to_date(YM,'YYYYMM'), -3),'YYYY'),2) when 0 then to_char(add_months(to_date(YM,'YYYYMM'), -3),'YYYY') || '/4 - ' || to_char(add_months(to_date(YM,'YYYYMM'), + 21),'YYYY') || '/3' else to_char(add_months(to_date(YM,'YYYYMM'), -15),'YYYY') || '/4 - ' || to_char(add_months(to_date(YM,'YYYYMM'), +9),'YYYY') || '/3' end as FILTER_2YEAR_APR, case when substring(YM,5,2) < 4 then 'Q1' when substring(YM,5,2) < 7 then 'Q2' when substring(YM,5,2) < 10 then 'Q3' else 'Q4' end as WS_DISP_QUARTER_JAN, case when substring(YM,5,2) < 4 then 'Q4' when substring(YM,5,2) < 7 then 'Q1' when substring(YM,5,2) < 10 then 'Q2' else 'Q3' end as WS_DISP_QUARTER_APR, case when substring(YM,5,2) < 7 then '1H' else '2H' end as WS_DISP_HALF_JAN, case when substring(YM,5,2) >= 4 and substring(YM,5,2) < 10 then '1H' else '2H' end as WS_DISP_HALF_APR, substring(YM,1,4) as WS_DISP_YEAR_JAN, to_char(add_months(to_date(YM,'YYYYMM'), -3),'YYYY') as WS_DISP_YEAR_APR, substring(YM,5,2) as WS_SORT_MONTH_JAN, to_char(add_months(to_date(YM,'YYYYMM'), -3),'MM') as WS_SORT_MONTH_APR from table1 ) select 1 demo from PP_WS_FLG;
2. 借助临时表中转数据
先把视图数据写入临时表,再从临时表插入目标表:
-- 创建临时表存储视图数据 create temp table tmp_view_data as select demo from schema1.tmp_v; -- 插入目标表 insert into schema2.tmp select demo from tmp_view_data;
3. 简化视图内的表达式逻辑
对视图中的复杂计算进行拆分,比如:
- 提前将YM字段转换为日期类型存储到原表,避免在视图中重复转换
- 把多分支CASE表达式拆分为多个步骤,减少优化器的解析复杂度
内容的提问来源于stack exchange,提问作者Manish Visave
相关产品推荐
相关产品推荐

