旋转多个属性并将其分组为“单个”属性(多对一)

时间:2019-04-30 16:17:20

标签: sql oracle pivot

因此,我有一个名为Value的表,该表与不同的“字段”相关联。请注意,其中一些字段具有相似的“名称”,但它们的名称不同。最终,我希望将这些“相似名称”作为结果集中的相同字段名称进行透视/分组

  VALUE_ID      VALUE_TX       FIELD_NAME     Version_ID
      1          Yes             Adult           1
      2          18              Age             1
      3          Black           Eye Color       1 
      4          Yes             Is_Adult        2
      5          25              Years_old       2
      6          Brown           Color_of_Eyes   2

我有一个名为Submitted的表,如下所示:

  Version_ID   Version_Name
     1         TEST_RUN
     2         REAL_RUN

我需要一个看起来像这样的结果集:

  Submitted_Name    Adult?     Age     Eye_Color
     TEST_RUN       Yes        18      Black
     REAL_RUN       Yes        25      Brown

我尝试了以下操作:

  SELECT * FROM (
                  select value_Tx, field_name, version_id
                    from VALUE
                )
          PIVOT (max (value_tx) for field_name in (('Adult', 'Is_Adult')   as 'Adult?', ('Age', 'Years_old') as 'Age', ('Eye Color', 'Color_of_Eyes') as 'Eye_Color')
           );

我在做什么错?请让我知道是否需要添加其他详细信息/数据。

谢谢!

我收到的错误消息如下:

ORA-00907: missing right parenthesis

2 个答案:

答案 0 :(得分:1)

我将更改子查询中的字段名称:

SELECT *
FROM (select value_Tx,
             (case when field_name in ('Adult', 'Is_Adult') then 'Adult?'
                        field_name in ('Age', 'Years_old') then 'Age'
                        field_name in ('Eye Color', 'Color_of_Eyes') then 'Eye_Color'                        
                   else field_name
              end) as field_name, version_id
      from VALUE
     )
PIVOT (max(value_tx) for field_name in ('Adult?', 'Age', 'Eye_Color'));

答案 1 :(得分:1)

您可以在数据透视子句的部分中对列别名使用双引号,并且我认为decode函数非常适合此问题。您可以考虑使用以下查询:

with value( value_id, value_tx, field_name, version_id ) as
(
 select 1 ,'Yes'  ,'Adult'        ,1 from dual union all
 select 2 ,'18'   ,'Age'          ,1 from dual union all
 select 3 ,'Black','Eye_Color'    ,1 from dual union all
 select 4 ,'Yes'  ,'Is_Adult'     ,2 from dual union all
 select 5 ,'25'   ,'Years_old'    ,2 from dual union all
 select 6 ,'Brown','Color_of_Eyes',2 from dual    
), Submitted( version_id, version_name ) as
(
 select 1 ,'TEST_RUN' from dual union all
 select 2 ,'REAL_RUN' from dual    
)    
  select * from
  (
    select s.version_name as "Submitted_Name", v.value_Tx, 
           decode(v.field_name,'Adult','Is_Adult','Age','Years_old','Eye_Color',
                               'Color_of_Eyes',v.field_name) field_name
      from value v
      join Submitted s 
        on s.version_id = v.version_id
     group by decode(v.field_name,'Adult','Is_Adult','Age','Years_old','Eye_Color',
                                  'Color_of_Eyes',v.field_name),
              v.value_Tx, s.Version_Name
  ) 
  pivot(
         max(value_tx) for field_name in ( 'Is_Adult' as "Adult?", 'Years_old' as "Age", 
                                           'Color_of_Eyes' as "Eye_Color" )
       );

Submitted_Name  Adult?  Age Eye_Color
REAL_RUN        Yes     25  Brown
TEST_RUN        Yes     18  Black

我认为,最好解决尽可能短的方法,例如,使用模块化算法甚至会更好,如下所示:

select *
  from
  (
    select s.version_name as "Submitted_Name", v.value_Tx, mod(v.value_id,3) as value_id
      from value v
      join Submitted s 
        on s.version_id = v.version_id
     group by v.value_Tx, s.version_name, mod(v.value_id,3)
  ) 
  pivot(
         max(value_tx) for value_id in ( 1 as "Adult?", 2 as "Age", 0 as "Eye_Color" )
       ) 

Demo