繁体   English   中英

如何从分组行中提取值到 Oracle SQL 中的特定列?

[英]How to extract values from grouped rows to specific columns in Oracle SQL?

假设我在 Oracle 中有这样的表:

+----------+-----------+--------+
| PersonId | ValueType | Value  |
+----------+-----------+--------+
|        1 | FirstName | John   |
|        1 | LastName  | Smith  |
|        2 | FirstName | John   |
|        2 | LastName  | Doe    |
|        2 | City      | London |
+----------+-----------+--------+

我怎样才能 select 数据如下:

+----------+-----------+----------+--------+
| PersonId | FirstName | LastName |  City  |
+----------+-----------+----------+--------+
|        1 | John      | Smith    |        |
|        2 | John      | Doe      | London |
+----------+-----------+----------+--------+

?

尝试使用case表达式对您的数据进行 pivot。

select
    PersonId,
    max(case when ValueType = 'FirstName' then Value end) as FirstName,
    max(case when ValueType = 'LastName' then Value end) as LastName,
    max(case when valueType = 'City' then value end) City
from yourTable
group by
    PersonId

您可以使用条件聚合 pivot 您的数据集:

select
    personid,
    max(case when valuetype = 'FirstName' then value end) firstname,
    max(case when valuetype = 'LastName'  then value end) lastname,
    max(case when valuetype = 'City'      then value end) city
from mytable
group by personid

旧的旋转方式(重要的是,符合 SQL 标准的方式)使用条件聚合,如 zealous 和 GMB 的答案所示。

Oracle 在很久以前的 11.1 版本中引入了pivot (以及相关的unpivot )算子。 我在下面说明了这种方法。 当我们需要一次 pivot(或反透视)多个列时,这些运算符特别有用; 但是,在这个线程中情况并非如此。

设置测试表:

create table person (personid, valuetype, value) as
  select 1, 'FirstName', 'John'   from dual union all 
  select 1, 'LastName' , 'Smith'  from dual union all
  select 2, 'FirstName', 'John'   from dual union all
  select 2, 'LastName' , 'Doe'    from dual union all
  select 2, 'City'     , 'London' from dual
;

查询和output:

select personid, firstname, lastname, city
from   person
pivot  (min(value) for valuetype in ( 'FirstName' as firstname
                                    , 'LastName'  as lastname
                                    , 'City'      as city
                                    )
       )
;

PERSONID FIRSTNAME LASTNAME  CITY  
-------- --------- --------- ------
       1 John      Smith        
       2 John      Doe       London

而且-也许更多是出于好奇(可能对其他更难的问题具有更严重的适用性)-这是使用match_recognize的解决方案,在 Oracle 12.1 中引入。 重要的是,与任何其他解决方案不同,这种方法不使用任何类型的聚合。

select personid, firstname, lastname, city
from   person
match_recognize
  (
    partition by personid
    measures  f.value as firstname
           ,  l.value as lastname
           ,  c.value as city
    pattern   ( (f|l|c)* )
    define    f as valuetype = 'FirstName'
         ,    l as valuetype = 'LastName'
         ,    c as valuetype = 'City'
  )
;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM