【问题标题】:split data in a single column into multiple columns in oracle在oracle中将单列中的数据拆分为多列
【发布时间】:2022-01-17 12:29:42
【问题描述】:

我的表:

Name Value
item_1 AB
item_2 2
item_3 B1
item_1 CD
item_1 EF
item_2 3
item_3 B2
item_4 ZZ

需要的输出:

item_1 item_2 item_3 item_4
AB 2 B1 ZZ
CD 3 B2 NULL
EF NULL NULL NULL

SQL 查询:

with item_1 as (select value from my_table where name  = 'item_1'),
item_2 as (select value from my_table where name  = 'item_2'),
item_3 as (select value from my_table where name  = 'item_3'),
item_4 as (select value from my_table where name  = 'item_4')
select item_1.value, item_2.value,item_3.value, item_4.value from item_1 cross join item_2 cross join item_3 cross join item_4;

如果我同时使用 pivot 和 MAX 聚合函数,查询将只显示相应项目的最大值,而不是显示所有值。

有没有什么方法可以在没有交叉连接的情况下将单个列拆分为多个列(使用上面查询中提到的 where 条件)。

【问题讨论】:

  • 你怎么知道哪些值是一起的——例如,'3' 与 'CD' 而不是 'EF' 一起;为什么输出中没有“B2”?是否还有另一列您没有显示链接事物(您可以使用它来分组为枢轴)?

标签: oracle join pivot decode


【解决方案1】:

使用ROW_NUMBER,然后使用PIVOT

SELECT item_1,
       item_2,
       item_3,
       item_4
FROM   (
  SELECT t.*,
         ROW_NUMBER() OVER (PARTITION BY name ORDER BY ROWNUM) AS rn
  FROM   table_name t
)
PIVOT (
  MAX(value) FOR name IN (
    'item_1' AS item_1,
    'item_2' AS item_2,
    'item_3' AS item_3,
    'item_4' AS item_4
  )
)

其中,对于样本数据:

CREATE TABLE table_name (Name, Value) AS
SELECT 'item_1', 'AB' FROM DUAL UNION ALL
SELECT 'item_2', '2'  FROM DUAL UNION ALL
SELECT 'item_3', 'B1' FROM DUAL UNION ALL
SELECT 'item_1', 'CD' FROM DUAL UNION ALL
SELECT 'item_1', 'EF' FROM DUAL UNION ALL
SELECT 'item_2', '3'  FROM DUAL UNION ALL
SELECT 'item_3', 'B2' FROM DUAL UNION ALL
SELECT 'item_4', 'ZZ' FROM DUAL;

输出:

ITEM_1 ITEM_2 ITEM_3 ITEM_4
AB 2 B1 ZZ
CD 3 B2 null
EF null null null

db小提琴here

【讨论】:

    【解决方案2】:

    这个怎么样?

    DF 列由row_number 分析函数计算,该函数按每个名称分区(并按值排序)。它从最后的列列表中被忽略,但它在GROUP BY 子句中的作用至关重要

    SQL> with test (name, value) as
      2    (select 'item_1', 'AB' from dual union all
      3     select 'item_2', '2'  from dual union all
      4     select 'item_3', 'B1' from dual union all
      5     select 'item_1', 'CD' from dual union all
      6     select 'item_1', 'EF' from dual union all
      7     select 'item_2', '3'  from dual union all
      8     select 'item_3', 'B2' from dual union all
      9     select 'item_4', 'ZZ' from dual
     10    ),
    

     11  temp as
     12    (select name, value,
     13       row_number() over (partition by name order by value) df
     14     from test
     15    )
     16  select
     17    max(case when name = 'item_1' then value end) item_1,
     18    max(case when name = 'item_2' then value end) item_2,
     19    max(case when name = 'item_3' then value end) item_3,
     20    max(case when name = 'item_4' then value end) item_4
     21  from temp
     22  group by df;
    
    ITEM_1 ITEM_2 ITEM_3 ITEM_4
    ------ ------ ------ ------
    AB     2      B1     ZZ
    CD     3      B2
    EF
    
    SQL>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-12
      • 2023-03-03
      • 2022-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-06
      相关资源
      最近更新 更多