从 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开发者命令行获取结果集

顺便说一句,避免像您的情况那样使用保留关键字,例如 setlevel。我需要引用它们才能使用。