在oracle中将单列中的数据拆分为多列

split data in a single column into multiple columns in oracle

my_table :

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 条件)。

这个怎么样?

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>

使用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<>fiddle here