【问题标题】:How to convert two or more rows into columns in OracleOracle中如何将两行或多行转换为列
【发布时间】:2020-07-20 08:53:45
【问题描述】:

我有一个表映射,它具有如下所示的列名和值。 (我有超过 20 列)

Original Data

我想把它转换成:

(0/NULL) Final Result

谁能帮帮忙。

我已经编写了以下查询,该查询仅适用于一列,但如何为超过两列执行此操作?

从 cte3 中选择 * 枢( min(1) for column1 in ( a , b , c , d ) ) 按id排序

【问题讨论】:

    标签: oracle oracle-sqldeveloper


    【解决方案1】:

    您需要使用条件聚合,因为PIVOT无法处理。

    SQL> WITH CTE(ID,COLUMN1,COLUMN2,COLUMN3,COLUMN4) AS
      2  (SELECT 1,'A','E','I','M' FROM DUAL UNION ALL
      3  SELECT 2,'B','F','J','N' FROM DUAL UNION ALL
      4  SELECT 3,'C','G','K','O' FROM DUAL UNION ALL
      5  SELECT 4,'D','H','L','P' FROM DUAL)
      6  --your query starts from here
      7  SELECT ID,
      8         COALESCE(SUM(CASE WHEN 'A' IN (COLUMN1,COLUMN2,COLUMN3,COLUMN4) THEN 1 END),0) AS A,
      9         COALESCE(SUM(CASE WHEN 'B' IN (COLUMN1,COLUMN2,COLUMN3,COLUMN4) THEN 1 END),0) AS B,
     10         COALESCE(SUM(CASE WHEN 'C' IN (COLUMN1,COLUMN2,COLUMN3,COLUMN4) THEN 1 END),0) AS C,
     11         COALESCE(SUM(CASE WHEN 'D' IN (COLUMN1,COLUMN2,COLUMN3,COLUMN4) THEN 1 END),0) AS D,
     12         COALESCE(SUM(CASE WHEN 'E' IN (COLUMN1,COLUMN2,COLUMN3,COLUMN4) THEN 1 END),0) AS E,
     13         COALESCE(SUM(CASE WHEN 'F' IN (COLUMN1,COLUMN2,COLUMN3,COLUMN4) THEN 1 END),0) AS F,
     14         COALESCE(SUM(CASE WHEN 'G' IN (COLUMN1,COLUMN2,COLUMN3,COLUMN4) THEN 1 END),0) AS G,
     15         COALESCE(SUM(CASE WHEN 'H' IN (COLUMN1,COLUMN2,COLUMN3,COLUMN4) THEN 1 END),0) AS H,
     16         COALESCE(SUM(CASE WHEN 'I' IN (COLUMN1,COLUMN2,COLUMN3,COLUMN4) THEN 1 END),0) AS I,
     17         COALESCE(SUM(CASE WHEN 'J' IN (COLUMN1,COLUMN2,COLUMN3,COLUMN4) THEN 1 END),0) AS J,
     18         COALESCE(SUM(CASE WHEN 'K' IN (COLUMN1,COLUMN2,COLUMN3,COLUMN4) THEN 1 END),0) AS K,
     19         COALESCE(SUM(CASE WHEN 'L' IN (COLUMN1,COLUMN2,COLUMN3,COLUMN4) THEN 1 END),0) AS L,
     20         COALESCE(SUM(CASE WHEN 'M' IN (COLUMN1,COLUMN2,COLUMN3,COLUMN4) THEN 1 END),0) AS M,
     21         COALESCE(SUM(CASE WHEN 'N' IN (COLUMN1,COLUMN2,COLUMN3,COLUMN4) THEN 1 END),0) AS N,
     22         COALESCE(SUM(CASE WHEN 'O' IN (COLUMN1,COLUMN2,COLUMN3,COLUMN4) THEN 1 END),0) AS O,
     23         COALESCE(SUM(CASE WHEN 'P' IN (COLUMN1,COLUMN2,COLUMN3,COLUMN4) THEN 1 END),0) AS P
     24    FROM CTE
     25  GROUP BY ID;
    
            ID  A  B  C  D  E  F  G  H  I  J  K  L  M  N  O  P
    ---------- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
             1  1  0  0  0  1  0  0  0  1  0  0  0  1  0  0  0
             2  0  1  0  0  0  1  0  0  0  1  0  0  0  1  0  0
             4  0  0  0  1  0  0  0  1  0  0  0  1  0  0  0  1
             3  0  0  1  0  0  0  1  0  0  0  1  0  0  0  1  0
    
    SQL>
    

    【讨论】:

      【解决方案2】:
      with q1 as (
      select 1 id, 'A' column1, 'E' column2, 'I' column3, 'M' column4 from dual
      union all
      select 2 id, 'B' column1, 'F' column2, 'J' column3, 'N' column4 from dual
      union all
      select 3 id, 'C' column1, 'G' column2, 'K' column3, 'O' column4 from dual
      union all
      select 4 id, 'D' column1, 'H' column2, 'L' column3, 'P' column4 from dual
      ),
      --select * from q1;
      q2 as (
      select 
         id,
         column1 as c1, case when column1 in ('A','B','C','D') then id end as c1p,
         column2 as c2, case when column2 in ('E','F','G','H') then 4+id end as c2p,
         column3 as c3, case when column3 in ('I','J','K','L') then 8+id end as c3p,
         column4 as c4, case when column4 in ('M','N','O','P') then 12+id end as c4p
      from q1
      order by 1
      ),
      --select * from q2;
      q3 as (
      select id, c1p as pos, c1 as val from q2
      union all
      select id, c2p as pos, c2 as val from q2
      union all
      select id, c3p as pos, c3 as val from q2
      union all
      select id, c4p as pos, c4 as val from q2
      order by 1,2
      ),
      --select * from q3;
      q4 as (
      select distinct pos, val from q3 order by 1
      ),
      --select * from q4;
      q5 as (
      select q3.id, q4.pos, q4.val, case when q3.val = q4.val then 1 else 0 end as nval
      from q3 
      partition by (q3.id)
      right outer join q4
      on (q3.pos = q4.pos)
      order by 1,2
      )
      --select * from q5;
      select 
         id, 
         sum(A) as A, sum(B) as B, sum(C) as C, sum(D) as D,
         sum(E) as E, sum(F) as F, sum(G) as G, sum(H) as H,
         sum(I) as I, sum(J) as J, sum(K) as K, sum(L) as L,
         sum(M) as M, sum(N) as N, sum(O) as O, sum(P) as P
      from q5
      pivot ( sum(nval) for val in (   
                 'A' as A,'B' as B,'C' as C,'D' as D,
                 'E' as E,'F' as F,'G' as G,'H' as H,
                 'I' as I,'J' as J,'K' as K,'L' as L,
                 'M' as M,'N' as N,'O' as O,'P' as P
              )
      )
      group by id
      order by 1
      ;
      

      Snapshot of Results as expected

      【讨论】:

      • 我无法对这些值进行硬编码,因为我每个月都有近 500 - 600 个不同的 ID 和不同的值。所有的 ID 都是唯一的。
      • 什么是硬编码... A,B,C,...和'A','B','C',...其他答案如何避免硬编码?即使那个人使用文字......一些替代语法可能是可能的,但很难给出你需要的答案而不知道更多。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-17
      • 2020-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多