【问题标题】:Oracle pivot rows to columns [duplicate]Oracle 将行转为列 [重复]
【发布时间】:2021-03-02 05:34:16
【问题描述】:

我有以下表格:

TABLE1
------
id name
1  n1
2  n2


TABLE2
------
id tipo valor
1  t1   v1
1  t2   v2
2  t1   v1
2  t2   v5
2  t3   v3

我正在努力得到:

id name t1 t2 t3
1  n1   v1 v2 -
2  n2   v1 v5 v3

有可能吗?我一直在寻找示例,但仍然不清楚。

谢谢!

【问题讨论】:

    标签: sql oracle pivot inner-join aggregate-functions


    【解决方案1】:

    一种选择是使用PIVOT 子句

    SELECT *
      FROM (SELECT t1.*, t2.tipo, t2.valor 
              FROM table1 t1 
              JOIN table2 t2 
                ON t2.id = t1.id)
     PIVOT 
     (
      MAX(valor) FOR tipo IN ( 't1' AS "t1", 't2' AS "t2", 't3' AS "t3" )
     )  
    

    但这是静态的,例如。需要更新 tipo 列的不同值。为了让它动态化,你可以创建一个函数

    CREATE OR REPLACE FUNCTION Get_Pivoted_Cols RETURN SYS_REFCURSOR IS
      v_recordset SYS_REFCURSOR;
      v_sql       VARCHAR2(32767); 
      v_cols      VARCHAR2(32767);      
    BEGIN
      SELECT LISTAGG( ''''||tipo||''' AS "'||tipo||'"' , ',' )
              WITHIN GROUP ( ORDER BY tipo )  
        INTO v_cols
        FROM ( SELECT DISTINCT tipo FROM table2 );
    
      v_sql := 'SELECT *
                  FROM (SELECT t1.*, t2.tipo, t2.valor 
                          FROM table1 t1 
                          JOIN table2 t2 
                            ON t2.id = t1.id)
                 PIVOT 
                 (
                  MAX(valor) FOR tipo IN ( '|| v_cols ||' )
                 )';   
    
      OPEN v_recordset FOR v_sql;
      RETURN v_recordset;
    END;
    /
    

    然后使用调用

    VAR rc REFCURSOR
    EXEC :rc := Get_Pivoted_Cols;
    PRINT rc
    

    来自 SQL 开发人员的控制台。

    Demo

    【讨论】:

      【解决方案2】:

      您可以使用条件聚合:

      select t1.id, t1.name,
          max(case when t2.typo = 't1' then t2.valor end) as t1,
          max(case when t2.typo = 't2' then t2.valor end) as t2,
          max(case when t2.typo = 't3' then t2.valor end) as t3
      from table1 t1
      inner join table2 t2 on t2.id = t1.id
      group by t1.id, t1.name
      

      这将返回不存在的 typos 的 null 值。如果你想要'-',你可以用coalesce()包围条件聚合,像这样:

          coalesce(max(case when t2.typo = 't1' then t2.valor end), '-') as t1
      

      【讨论】:

        猜你喜欢
        • 2019-10-14
        • 2020-02-23
        • 2014-01-27
        • 1970-01-01
        • 2021-08-07
        • 2018-11-11
        • 2019-09-13
        • 2021-03-30
        • 1970-01-01
        相关资源
        最近更新 更多