PostgreSQL如何按动态条件选择性执行IF语句并拼接UNION查询结果
动态选择查询拼接UNION ALL的实现方案
你可以根据实际场景选择以下两种实现方式:
方案1:静态SQL通用实现(推荐)
无需编写动态SQL,兼容绝大多数SQL数据库,数据库优化器会自动跳过不需要执行的查询,不会产生额外性能开销:
-- 此处的参数列表为你提到的自动填充的('Daily','Yearly')部分,可直接替换为实际填充逻辑 WITH allowed_report_types(type) AS ( SELECT 'Daily' UNION ALL SELECT 'Yearly' ) -- Daily查询 SELECT * FROM ( -- 此处替换为你已经写好的Daily查询语句 SELECT 列1, 列2, 列3 FROM 日统计表 WHERE 业务条件 ) t_daily WHERE EXISTS (SELECT 1 FROM allowed_report_types WHERE type = 'Daily') UNION ALL -- Monthly查询 SELECT * FROM ( -- 此处替换为你已经写好的Monthly查询语句 SELECT 列1, 列2, 列3 FROM 月统计表 WHERE 业务条件 ) t_monthly WHERE EXISTS (SELECT 1 FROM allowed_report_types WHERE type = 'Monthly') UNION ALL -- Yearly查询 SELECT * FROM ( -- 此处替换为你已经写好的Yearly查询语句 SELECT 列1, 列2, 列3 FROM 年统计表 WHERE 业务条件 ) t_yearly WHERE EXISTS (SELECT 1 FROM allowed_report_types WHERE type = 'Yearly')
实现逻辑说明:如果对应报告类型不在允许的列表中,子查询外层的WHERE条件会恒假,数据库会直接返回空结果,不会执行内层你写的实际查询逻辑,符合你要求的仅执行部分查询的需求。
方案2:动态SQL实现
如果需要完全将不需要的查询从执行语句中剔除,可以采用对应数据库的动态SQL语法,以下为MySQL示例:
-- 自动填充的允许报告类型参数 SET @allowed_types = 'Daily,Yearly'; SET @exec_sql = ''; -- 拼接Daily查询 IF FIND_IN_SET('Daily', @allowed_types) THEN SET @exec_sql = 'SELECT 列1,列2,列3 FROM 日统计表 WHERE 业务条件'; END IF; -- 拼接Monthly查询 IF FIND_IN_SET('Monthly', @allowed_types) THEN IF @exec_sql != '' THEN SET @exec_sql = CONCAT(@exec_sql, ' UNION ALL '); END IF; SET @exec_sql = CONCAT(@exec_sql, 'SELECT 列1,列2,列3 FROM 月统计表 WHERE 业务条件'); END IF; -- 拼接Yearly查询 IF FIND_IN_SET('Yearly', @allowed_types) THEN IF @exec_sql != '' THEN SET @exec_sql = CONCAT(@exec_sql, ' UNION ALL '); END IF; SET @exec_sql = CONCAT(@exec_sql, 'SELECT 列1,列2,列3 FROM 年统计表 WHERE 业务条件'); END IF; -- 执行拼接完成的SQL PREPARE stmt FROM @exec_sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
注意事项
所有参与UNION ALL拼接的查询,返回的字段数量、字段顺序、字段类型必须完全一致,否则会执行报错。
内容的提问来源于stack exchange,提问作者sharkyenergy
相关产品推荐
相关产品推荐

