如何选择行数据作为列标题并根据Oracle中的标题排列值?

时间:2016-09-06 16:41:24

标签: sql oracle

考虑我有一个表作为Employee_Details,其中维护了Employee_Name和Employee_Level。

例如

Employee_Details **

每个Employee_Level应该是我的输出列,所有Employee_name应该根据employee_level按字母顺序排列

1 个答案:

答案 0 :(得分:1)

你提到你的Oracle版本(在你的情况下为10g)是件好事 - 在大多数情况下应该包含在你的问题中。

这排除了PIVOT的使用 - 如此处提供的解决方案:Need to arrange employee names as per their city column wise(但是,我在本答案的最后提供了“手动”PIVOT解决方案)。

另一种方法是使用完全外连接,就像这样。由于迭代的完全外连接,您必须小心连接条件(注意在最后一个连接条件下使用NVL)。

with
     employee_details ( employee_name, employee_level ) as (
       select 'Vingesh' , 'Manager'           from dual union all
       select 'Ragul'   , 'Senior Manager'    from dual union all
       select 'Nivithen', 'Senior Manager'    from dual union all
       select 'Joe'     , 'Associate Manager' from dual union all
       select 'Arul'    , 'Manager'           from dual union all
       select 'Rishi'   , 'Manager'           from dual
     ),
     prep ( employee_name, employee_level, rn ) as (
       select employee_name, employee_level, 
              row_number() over (partition by employee_level order by employee_name)
       from   employee_details
     )
select p1.employee_name as associate_manager,
       p2.employee_name as manager,
       p3.employee_name as senior_manager
from   (select employee_name, rn from prep where employee_level = 'Associate Manager') p1
       full outer join
       (select employee_name, rn from prep where employee_level = 'Manager')           p2
           on p1.rn = p2.rn
       full outer join
       (select employee_name, rn from prep where employee_level = 'Senior Manager')    p3
           on nvl(p1.rn, p2.rn) = p3.rn
order by 1, 2, 3
;

ASSOCIATE_MANAGER MANAGER           SENIOR_MANAGER
----------------- ----------------- -----------------
Joe               Arul              Nivithen
                  Rishi             Ragul
                  Vingesh

3 rows selected.

您也可以使用相同的“prep”因子子查询,并使用下面的select语句替换迭代的完整外连接。您可能想尝试两种解决方案,看看哪种解决方案更快;结果应该是一样的。

select min(case when employee_level = 'Associate Manager' 
                then employee_name end) as associate_manager,
       min(case when employee_level = 'Manager' 
                then employee_name end) as manager,
       min(case when employee_level = 'Senior Manager' 
                then employee_name end) as senior_manager
from   prep
group by rn
order by 1, 2, 3
;