从 SQL table 在 SQL 中创建 Pivot 视图
Create Pivot view in SQL from a SQL table
我有以下tableTEMP
我想使用 SQL 创建一个透视视图,按 CATEGORY
ASC 排序,按 LEVEL
DESC 和 SET
ASC 排序并填写 value
.
预期输出:
我尝试了以下代码,但无法找到引发错误的聚合部分的解决方法:
SELECT *
FROM
(SELECT
SET, LEVEL, CATEGORY, VALUE
FROM
TEMP
ORDER BY
CATEGORY ASC, LEVEL DESC, SET ASC) x
PIVOT
(value(VALUE) FOR RISK_LEVEL IN ('X','Y','Z') AND CATEGORY IN ('ABC', 'DEF', 'GHI', 'JKL')) p
此外,我想知道是否有任何方法可以动态添加列并为具有相同列的任何 table 到达此视图(这样可以避免硬编码)。
我知道我们可以在 Excel 中执行此操作并转置它,但我希望数据以这种格式存储在数据库中。
可能会创建存储函数(或过程)以便为动态透视创建 SQL,并将结果集加载到类型的变量中SYS_REFCURSOR
:
CREATE OR REPLACE FUNCTION Get_Categories_RS RETURN SYS_REFCURSOR IS
v_recordset SYS_REFCURSOR;
v_sql VARCHAR2(32767);
v_cols_1 VARCHAR2(32767);
v_cols_2 VARCHAR2(32767);
BEGIN
SELECT LISTAGG( ''''||"level"||''' AS "'||"level"||'"' , ',' )
WITHIN GROUP ( ORDER BY "level" DESC )
INTO v_cols_1
FROM (
SELECT DISTINCT "level"
FROM temp
);
SELECT LISTAGG( 'MAX(CASE WHEN category = '''||category||''' THEN "'||"level"||'" END) AS "'||"level"||'_'||category||'"' , ',' )
WITHIN GROUP ( ORDER BY category, "level" DESC )
INTO v_cols_2
FROM (
SELECT DISTINCT "level", category
FROM temp
);
v_sql :=
'SELECT "set", '|| v_cols_2 ||'
FROM
(
SELECT *
FROM temp
PIVOT
(
MAX(value) FOR "level" IN ( '|| v_cols_1 ||' )
)
)
GROUP BY "set"
ORDER BY "set"';
OPEN v_recordset FOR v_sql;
RETURN v_recordset;
END;
其中我使用了两个级别的数据透视:第一个是在涉及 PIVOT
子句的内部查询中,第二个是在具有条件聚合逻辑的外部查询中。需要注意的是levels的顺序应该在预期结果内按降序排列(Z
, Y
, X
)才符合描述。
然后调用
VAR rc REFCURSOR
EXEC :rc := Get_Categories_RS;
PRINT rc
从SQL开发者命令行获取结果集
顺便说一句,避免像您的情况那样使用保留关键字,例如 set
和 level
。我需要引用它们才能使用。
我有以下tableTEMP
我想使用 SQL 创建一个透视视图,按 CATEGORY
ASC 排序,按 LEVEL
DESC 和 SET
ASC 排序并填写 value
.
预期输出:
我尝试了以下代码,但无法找到引发错误的聚合部分的解决方法:
SELECT *
FROM
(SELECT
SET, LEVEL, CATEGORY, VALUE
FROM
TEMP
ORDER BY
CATEGORY ASC, LEVEL DESC, SET ASC) x
PIVOT
(value(VALUE) FOR RISK_LEVEL IN ('X','Y','Z') AND CATEGORY IN ('ABC', 'DEF', 'GHI', 'JKL')) p
此外,我想知道是否有任何方法可以动态添加列并为具有相同列的任何 table 到达此视图(这样可以避免硬编码)。
我知道我们可以在 Excel 中执行此操作并转置它,但我希望数据以这种格式存储在数据库中。
可能会创建存储函数(或过程)以便为动态透视创建 SQL,并将结果集加载到类型的变量中SYS_REFCURSOR
:
CREATE OR REPLACE FUNCTION Get_Categories_RS RETURN SYS_REFCURSOR IS
v_recordset SYS_REFCURSOR;
v_sql VARCHAR2(32767);
v_cols_1 VARCHAR2(32767);
v_cols_2 VARCHAR2(32767);
BEGIN
SELECT LISTAGG( ''''||"level"||''' AS "'||"level"||'"' , ',' )
WITHIN GROUP ( ORDER BY "level" DESC )
INTO v_cols_1
FROM (
SELECT DISTINCT "level"
FROM temp
);
SELECT LISTAGG( 'MAX(CASE WHEN category = '''||category||''' THEN "'||"level"||'" END) AS "'||"level"||'_'||category||'"' , ',' )
WITHIN GROUP ( ORDER BY category, "level" DESC )
INTO v_cols_2
FROM (
SELECT DISTINCT "level", category
FROM temp
);
v_sql :=
'SELECT "set", '|| v_cols_2 ||'
FROM
(
SELECT *
FROM temp
PIVOT
(
MAX(value) FOR "level" IN ( '|| v_cols_1 ||' )
)
)
GROUP BY "set"
ORDER BY "set"';
OPEN v_recordset FOR v_sql;
RETURN v_recordset;
END;
其中我使用了两个级别的数据透视:第一个是在涉及 PIVOT
子句的内部查询中,第二个是在具有条件聚合逻辑的外部查询中。需要注意的是levels的顺序应该在预期结果内按降序排列(Z
, Y
, X
)才符合描述。
然后调用
VAR rc REFCURSOR
EXEC :rc := Get_Categories_RS;
PRINT rc
从SQL开发者命令行获取结果集
顺便说一句,避免像您的情况那样使用保留关键字,例如 set
和 level
。我需要引用它们才能使用。