如何将具有排名值的列转换为oracle中的行

Posted

技术标签:

【中文标题】如何将具有排名值的列转换为oracle中的行【英文标题】:How to convert column with Rank Value into rows in oracle 【发布时间】:2019-10-07 03:38:28 【问题描述】:

我有一些查询,返回以下数据:

Month Year EMP_ID EMP_NAME RANK
Jan   2019  1       EmpName1    1
Jan   2019  2       EmpName2    2
Jan   2019  3       EmpName3    3
Jan   2019  4       EmpName4    4
Jan   2019  5       EmpName5    5
FEB   2019  1       EmpName1    1
FEB   2019  2       EmpName2    2
FEB   2019  3       EmpName3    3
FEB   2019  4       EmpName4    4
FEM   2019  5       EmpName5    5

我想以以下格式显示此数据:

Month Year  Rank1        Rank2     Rank3      Rank4       Rank5
Jan   2019 EmpName1    EmpNAme2   EmpName3  EmpName4    EmpName5
Feb   2019 EmpName1    EmpNAme2   EmpName3  EmpName4    EmpName5

【问题讨论】:

谷歌“SQL 数据透视表” 【参考方案1】:

如果版本 Oracle 11+ 使用枢轴

with tbl as
(SELECT 'JAN' mon,   '2019' y, '1' rn, 'EmpName1' name from dual
UNION ALL 
select 'JAN', '2019', '2', 'EmpName2' from dual 
union all 
select 'JAN', '2019', '3', 'EmpName3' from dual
union all
select 'JAN', '2019', '4', 'EmpName4' from dual
union all
select 'JAN', '2019', '5', 'EmpName5' from dual
union all
select 'FEB', '2019', '1', 'EmpName1' from dual
union all
select 'FEB', '2019', '2', 'EmpName2' from dual
union all
select 'FEB', '2019', '3', 'EmpName3' from dual
union all
select 'FEB', '2019', '4', 'EmpName4' from dual
union all
select 'FEB', '2019', '5', 'EmpName5' from dual)
select *  
from (select mon, y, rn, name 
from tbl)
pivot
(
  MAX(name)
  FOR rn
  IN ('1', '2', '3', '4', '5')
)
ORDER BY 1

如果是 10 克

with tbl as
(SELECT 'JAN' mon,   '2019' y, '1' rn, 'EmpName1' name from dual
UNION ALL 
select 'JAN', '2019', '2', 'EmpName2' from dual 
union all 
select 'JAN', '2019', '3', 'EmpName3' from dual
union all
select 'JAN', '2019', '4', 'EmpName4' from dual
union all
select 'JAN', '2019', '5', 'EmpName5' from dual
union all
select 'FEB', '2019', '1', 'EmpName1' from dual
union all
select 'FEB', '2019', '2', 'EmpName2' from dual
union all
select 'FEB', '2019', '3', 'EmpName3' from dual
union all
select 'FEB', '2019', '4', 'EmpName4' from dual
union all
select 'FEB', '2019', '5', 'EmpName5' from dual)
select 
mon,
y,
min(decode(rn, 1, nm, NULL)) Rank1 ,
min(decode(rn, 2, nm, NULL)) Rank2 ,
min(decode(rn, 3, nm, NULL)) Rank3 ,
min(decode(rn, 4, nm, NULL)) Rank4 ,
min(decode(rn, 5, nm, NULL)) Rank5 
from
 (
  select
  tbl.mon,
  tbl.y,
  tbl.rn,
  max(name) nm
  from
  tbl
  group by tbl.mon, tbl.y, tbl.rn
 )
group by mon, y

【讨论】:

这么好的和全面的答案。【参考方案2】:

只需使用 Conditional Aggregationcase..when 表达式:

select Month, Year,
       max( case when emp_id = 1 then Emp_Name end ) as EmpName1,
       max( case when emp_id = 2 then Emp_Name end ) as EmpName2,
       max( case when emp_id = 3 then Emp_Name end ) as EmpName3,
       max( case when emp_id = 4 then Emp_Name end ) as EmpName4,
       max( case when emp_id = 5 then Emp_Name end ) as EmpName5
  from tab
 group by Month, Year 

【讨论】:

以上是关于如何将具有排名值的列转换为oracle中的行的主要内容,如果未能解决你的问题,请参考以下文章

如何将具有重复值的行转换为列?

如何将具有数字值的 char 数据类型的列转换为数字数据类型

如何将 df 中的列转换为具有日期时间格式的纪元,反之亦然?

Vertica SQL - 将排名号转换为自己的列

将具有多行值的列标准化为每个单元格的单个值

将分隔字段转换为具有名称和值的行