Amazon Redshift中动态选择tb2表的name或nm列的实现方案咨询
Amazon Redshift中动态选择tb2表的name或nm列的实现方案咨询
嗨,我来帮你搞定这个Redshift里的动态选列问题!既然你试过information_schema和pg_get_late_data_columns都没效果,那咱们换个思路,用Redshift支持的动态SQL结合底层系统表来解决。
根据你的需求:tb2表每天刷新,只会存在name或nm其中一列,不会同时出现,我们可以通过以下两种方案实现动态选择对应列:
方案一:使用PL/pgSQL匿名块(适合脚本或一次性执行)
这个方案会先检查目标列是否存在,再生成对应的查询语句执行:
DO $$ DECLARE has_name_col BOOLEAN; query_text VARCHAR; BEGIN -- 检查tb2表是否存在name列 SELECT EXISTS ( SELECT 1 FROM pg_attribute WHERE attrelid = 'tb2'::regclass -- 定位tb2表 AND attname = 'name' -- 检查列名 AND attnum > 0 -- 排除系统隐藏列 AND NOT attisdropped -- 排除已删除的列 ) INTO has_name_col; -- 根据列存在情况构造查询语句 IF has_name_col THEN query_text := 'SELECT name FROM tb2;'; ELSE -- 题目明确两列不同时存在,直接选nm列 query_text := 'SELECT nm FROM tb2;'; END IF; -- 执行动态生成的查询 EXECUTE query_text; END $$;
方案二:使用UNION ALL构造查询(适合嵌入报表或其他查询)
如果需要把结果作为一个普通查询的一部分,可以用这种方式,通过别名统一输出列名:
SELECT target_column FROM ( -- 当name列存在时,查询name列 SELECT name AS target_column FROM tb2 WHERE EXISTS ( SELECT 1 FROM pg_attribute WHERE attrelid = 'tb2'::regclass AND attname = 'name' AND attnum > 0 AND NOT attisdropped ) UNION ALL -- 当nm列存在时,查询nm列 SELECT nm AS target_column FROM tb2 WHERE EXISTS ( SELECT 1 FROM pg_attribute WHERE attrelid = 'tb2'::regclass AND attname = 'nm' AND attnum > 0 AND NOT attisdropped ) ) AS dynamic_result;
补充说明:
- 这里用
pg_attribute系统表来检查列是否存在,它是Redshift的底层系统表,权限要求低,通常能绕过information_schema可能遇到的问题 - 因为你明确说明两列不会同时存在,所以无需处理冲突情况,逻辑可以简化
备注:内容来源于stack exchange,提问作者Chavi sikand
相关产品推荐
相关产品推荐

