透视多个属性并将它们分组为“单个”属性(多对一)

问题描述 投票:0回答:2

所以我有一个名为Value的表,它与不同的'Fields'相关联。请注意,其中一些字段具有相似的“名称”,但它们的命名方式不同。最终,我希望将这些“相似名称”在结果集中旋转/分组为相同的字段名称

  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
sql oracle pivot
2个回答
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
投票

你可以在pivot子句的部分中使用双引号作为列别名,我认为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

© www.soinside.com 2019 - 2024. All rights reserved.