如何将具有重复值的行转换为列?

use*_*055 5 sql oracle pivot

我试图转动我的表但保留额外的行(在我的示例中为eeeeee)在Oracle SQL中有没有办法做到这一点?

select * from (
select 
    mat_table.material, attribute_table.attribute, attribute_table.value
  from 
    mat_table mat_table
    inner join 
    attribute_table on mat_table.rel= attribute_table.rel
    where 




      material = 'Material_A' 
            )


material    |attribute|  value
_____________________________________

Material_A  |aaaaaa    | 
Material_A  |bbbbbb    |       hello
Material_A  |cccccc    |       val_1
Material_A  |dddddd    |       2
Material_A  |eeeeee    |       15
Material_A  |eeeeee    |       16
Material_A  |eeeeee    |       24 
Run Code Online (Sandbox Code Playgroud)

当我在where子句下使用pivot时

    pivot (
    max(attribute) as max_value for attribute IN ( 'aaaaaa', 
                                                   'bbbbbb', 
                                                   'cccccc', 
                                                   'dddddd', 
                                                   'eeeeee'
                                      ))
Run Code Online (Sandbox Code Playgroud)

我越来越接近我想要的东西但是对于eeeee我只得到一个值

material    |aaaaaa | bbbbbb | cccccc | dddddd | eeeeee |
__________________________________________________________
Material_A  |       | hello  | val_1  | 2      | 24     |
Run Code Online (Sandbox Code Playgroud)

但我想要的是什么

material    |aaaaaa | bbbbbb | cccccc | dddddd | eeeeee_1 | eeeeee_2 | eeeeee_3 |
   __________________________________________________________________________________
Material_A  |       | hello  | val_1  | 2      | 15            16    |     24
Run Code Online (Sandbox Code Playgroud)

Dr *_*Wit 2

如果总是有 3 个值,那么eeeeee您可以按如下方式执行

SQL> with mat_table (material, attribute, value) as
  2  (
  3  select 'Material_A', 'aaaaaa', null from dual
  4  union all select 'Material_A', 'bbbbbb', 'hello' from dual
  5  union all select 'Material_A', 'cccccc', 'val_1' from dual
  6  union all select 'Material_A', 'dddddd', '2' from dual
  7  union all select 'Material_A', 'eeeeee', '15' from dual
  8  union all select 'Material_A', 'eeeeee', '16' from dual
  9  union all select 'Material_A', 'eeeeee', '24' from dual
 10  )
 11  select *
 12    from (select t.*,
 13                 row_number() over(partition by attribute order by value) rn
 14            from mat_table t)
 15  pivot (max(value) for (attribute, rn) in
 16  (
 17   ('aaaaaa', 1), ('bbbbbb', 1), ('cccccc', 1), ('dddddd', 1),
 18   ('eeeeee', 1), ('eeeeee', 2), ('eeeeee', 3)
 19  ));

MATERIAL   'aaaa 'bbbb 'cccc 'dddd 'eeee 'eeee 'eeee
---------- ----- ----- ----- ----- ----- ----- -----
Material_A       hello val_1 2     15    16    24
Run Code Online (Sandbox Code Playgroud)

但是,如果您希望 Oracle 为任意数量的值动态创建列,那么eeeeee这是不可能的。

请在此处阅读详细说明Oracle Dynamic Pivoting

attribute您可以为和的任意组合生成 XML,value但如果您想使用 SQL 显示结果,那么最终必须指定所有列(替代方法是在客户端解析 XML)。

SQL> with mat_table (material, attribute, value) as
  2  (
  3  select 'Material_A', 'aaaaaa', null from dual
  4  union all select 'Material_A', 'bbbbbb', 'hello' from dual
  5  union all select 'Material_A', 'cccccc', 'val_1' from dual
  6  union all select 'Material_A', 'dddddd', '2' from dual
  7  union all select 'Material_A', 'eeeeee', '15' from dual
  8  union all select 'Material_A', 'eeeeee', '16' from dual
  9  union all select 'Material_A', 'eeeeee', '24' from dual
 10  )
 11  select material, x.*
 12  from mat_table
 13  pivot xml (count(*) as dummy for (attribute, value) in (any, any))
 14  -- parsing output
 15  , xmltable('/PivotSet' passing attribute_value_xml
 16             columns
 17               aaaaaa varchar2(10) path '/PivotSet/item[column="aaaaaa"]/column[2]',
 18               bbbbbb varchar2(10) path '/PivotSet/item[column="bbbbbb"]/column[2]',
 19               cccccc varchar2(10) path '/PivotSet/item[column="cccccc"]/column[2]',
 20               dddddd varchar2(10) path '/PivotSet/item[column="dddddd"]/column[2]',
 21               eeeeee_1 varchar2(10) path '/PivotSet/item[column="eeeeee"][1]/column[2]',
 22               eeeeee_2 varchar2(10) path '/PivotSet/item[column="eeeeee"][2]/column[2]',
 23               eeeeee_3 varchar2(10) path '/PivotSet/item[column="eeeeee"][3]/column[2]') x;

MATERIAL   AAAAAA     BBBBBB     CCCCCC     DDDDDD     EEEEEE_1   EEEEEE_2   EEEEEE_3
---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
Material_A            hello      val_1      2          15         16         24
Run Code Online (Sandbox Code Playgroud)

在这种情况下,无法保证 EEEEEE_1/EEEEEE_2/EEEEEE_3 会严格按照此顺序为 15/16/24。