5

我尝试旋转我的表但保留额外的行(在我的示例 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 

当我在 where 子句下使用 pivot

    pivot (
    max(attribute) as max_value for attribute IN ( 'aaaaaa', 
                                                   'bbbbbb', 
                                                   'cccccc', 
                                                   'dddddd', 
                                                   'eeeeee'
                                      ))

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

material    |aaaaaa | bbbbbb | cccccc | dddddd | eeeeee |
__________________________________________________________
Material_A  |       | hello  | val_1  | 2      | 24     |

但我想要的是

material    |aaaaaa | bbbbbb | cccccc | dddddd | eeeeee_1 | eeeeee_2 | eeeeee_3 |
   __________________________________________________________________________________
Material_A  |       | hello  | val_1  | 2      | 15            16    |     24
4

2 回答 2

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

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

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

您可以为任何组合生成 XML,attribute但是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

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

于 2018-12-06T03:19:04.117 回答
1

编辑:TS 评论说它不适用于多种材料。所以我扩展了答案来解释这一点。

您可以简单地将 row_number (按材料、属性分区)连接到第一个查询中的属性。如果您愿意,可以按值添加排序。为了考虑多种材料,row_number 也按材料分区。这意味着不同材质的相同属性将获得相同的名称并最终出现在同一列中。

替换attribute_table.attribute

concat(attribute_table.attribute,'_', row_number() over (partition by attribute_table.material, attribute_table.attribute order by attribute_table.attribute, attribute_table.value))

完整的代码和结果:

with mat_table  as
  (
  select 'Material_A' as material, 'aaaaaa' as attribute, null as value
  union all select 'Material_A', 'bbbbbb', 'hello' 
  union all select 'Material_A', 'cccccc', 'val_1' 
  union all select 'Material_A', 'dddddd', '2' 
  union all select 'Material_A', 'eeeeee', '15' 
  union all select 'Material_A', 'eeeeee', '16' 
  union all select 'Material_A', 'eeeeee', '24' 
  union all select 'Material_B' , 'aaaaaa', 'lol' 
  union all select 'Material_B', 'bbbbbb', 'hi' 
  union all select 'Material_B', 'cccccc', 'max_val' 
  union all select 'Material_B', 'dddddd', '4' 
  union all select 'Material_B', 'eeeeee', '67' 
  union all select 'Material_B', 'eeeeee', '99' 
  union all select 'Material_B', 'eeeeee', null
  )

select *
from (
    select t.material,
            t.value ,
            concat(t.attribute,'_', row_number() over (partition by t.material , t.attribute order by t.attribute, t.value)) as numbered_attribute
    from mat_table t) as d
pivot (
    max(d.value)  
    for numbered_attribute IN ( [aaaaaa_1],  
                                [bbbbbb_1], 
                                [cccccc_1], 
                                [dddddd_1], 
                                [eeeeee_1],
                                [eeeeee_2],
                                [eeeeee_3]
                             )) as total
    order by total.material

注意:我使用的是 SQL-Server。也许您必须更改一些语法,例如 [eeeeee_3] => 'eeeeee_3'

带有编号属性的基表:

基表

旋转后的最终结果:

最后结果

于 2018-12-10T00:37:08.533 回答