求助:Oracle中如何用动态SQL实现按财年(FY)转置日期列
Oracle 按财年转置日期列的动态SQL解决方案
静态PIVOT示例(适用于已知固定FY值的场景)
如果财年(FY)值固定,可直接用静态PIVOT语句实现需求:
SELECT ID, "Holiday Desc", "FY23", "FY24" FROM ( SELECT ID, FY, CAL_DATE, "Holiday Desc" FROM your_table_name -- 替换为你的实际表名 ) PIVOT ( MAX(CAL_DATE) FOR FY IN ('FY23' AS "FY23", 'FY24' AS "FY24") ) ORDER BY ID, "Holiday Desc";
动态PIVOT解决方案(适用于FY值不固定的场景)
若FY值会新增或变化,静态SQL需频繁修改,此时用动态SQL可自动适配所有FY值:
DECLARE v_pivot_cols VARCHAR2(1000); v_sql VARCHAR2(2000); BEGIN -- 自动获取所有唯一FY值,拼接成PIVOT需要的格式 SELECT LISTAGG('''' || FY || ''' AS "' || FY || '"', ', ') WITHIN GROUP (ORDER BY FY) INTO v_pivot_cols FROM (SELECT DISTINCT FY FROM your_table_name); -- 替换为实际表名 -- 拼接完整的动态查询语句 v_sql := ' SELECT ID, "Holiday Desc", ' || v_pivot_cols || ' FROM ( SELECT ID, FY, CAL_DATE, "Holiday Desc" FROM your_table_name ) PIVOT ( MAX(CAL_DATE) FOR FY IN (' || v_pivot_cols || ') ) ORDER BY ID, "Holiday Desc"'; -- 执行动态SQL EXECUTE IMMEDIATE v_sql; -- 若需在PL/SQL中输出结果,可取消以下注释 -- FOR rec IN (EXECUTE IMMEDIATE v_sql) LOOP -- DBMS_OUTPUT.PUT_LINE(rec.ID || ' | ' || rec."Holiday Desc" || ' | ' || rec.FY23 || ' | ' || rec.FY24); -- END LOOP; END; /
关键说明
- 使用
LISTAGG函数将所有唯一FY值拼接为PIVOT子句所需的列格式,自动适配新增的FY值 MAX(CAL_DATE)用于聚合,因每个ID + Holiday Desc + FY组合仅对应一条记录,用MAX或MIN均可保证返回唯一值- 执行动态SQL时,需确保当前用户拥有对应表的查询权限
内容的提问来源于stack exchange,提问作者prtk
相关产品推荐
相关产品推荐

