[英]How to extract values from grouped rows to specific columns in Oracle SQL?
Suppose I have a table like this in Oracle:假设我在 Oracle 中有这样的表:
+----------+-----------+--------+
| PersonId | ValueType | Value |
+----------+-----------+--------+
| 1 | FirstName | John |
| 1 | LastName | Smith |
| 2 | FirstName | John |
| 2 | LastName | Doe |
| 2 | City | London |
+----------+-----------+--------+
How can I select the data like the following:我怎样才能 select 数据如下:
+----------+-----------+----------+--------+
| PersonId | FirstName | LastName | City |
+----------+-----------+----------+--------+
| 1 | John | Smith | |
| 2 | John | Doe | London |
+----------+-----------+----------+--------+
? ?
Try with case
expressions to pivot your data.尝试使用
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
You can pivot your dataset with conditional aggregation:您可以使用条件聚合 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
The old way of pivoting (and, importantly, the SQL Standard compliant way) uses conditional aggregation, as shown in zealous's and GMB's answers.旧的旋转方式(重要的是,符合 SQL 标准的方式)使用条件聚合,如 zealous 和 GMB 的答案所示。
Oracle introduced the pivot
(and related unpivot
) operator in version 11.1, that is, a very long time ago. Oracle 在很久以前的 11.1 版本中引入了
pivot
(以及相关的unpivot
)算子。 I illustrate that approach below.我在下面说明了这种方法。 These operators are particularly helpful when we need to pivot (or unpivot) multiple columns at a time;
当我们需要一次 pivot(或反透视)多个列时,这些运算符特别有用; however, that's not the case in this thread.
但是,在这个线程中情况并非如此。
Setting up the test table:设置测试表:
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
;
Query and output:查询和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
And - perhaps more as a curiosity (with more serious applicability, maybe, to other, harder problems) - here is a solution using match_recognize
, introduced in Oracle 12.1.而且-也许更多是出于好奇(可能对其他更难的问题具有更严重的适用性)-这是使用
match_recognize
的解决方案,在 Oracle 12.1 中引入。 Importantly, unlike any other solutions, this approach does not use aggregation of any kind.重要的是,与任何其他解决方案不同,这种方法不使用任何类型的聚合。
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.