PL / SQL将行转换为分组列

时间:2012-11-16 01:56:10

标签: plsql

我不确定如何表达这个问题,但我试图将行值转换为PL / SQL中的列。我不是新手,但我无法想象如何去做这件事。我有以下表格数据:

名称责任


乔销售
史蒂夫销售
保罗Exec的
皮特经理
约翰Exec的
罗杰秒
Scott Exec

我需要创建一个将返回并显示数据的查询,如下所示:

销售经理Exec的二段


乔皮特约翰罗杰
史蒂夫空斯科特空
空空保罗空

我面临的问题是行数据无论如何都与彼此无关。甚至可以这样做吗?

我感谢任何人都能提供的任何帮助。 感谢。

1 个答案:

答案 0 :(得分:0)

首先,如果你将来给我们你的数据库版本会更好。例如,如果你有Oracle 11g,即使它不是你想要的,你可以用PIVOT <做类似的事情/ p>

with pivot_data as (select rownum as no,emp_name,job_name from (
select 'Joe' as emp_name,'Sales' as job_name from dual union all
select 'Steve','Sales'    from dual union all
select 'Paul','Exec'     from dual union all
select 'Pete','Manager'  from dual union all
select 'John','Exec'     from dual union all
select 'Roger','Sec'      from dual union all
select 'Scott','Exec'     from dual))
select "'Sales'" as Sales,"'Exec'" as Exec,"'Sec'" as Sec,"'Manager'" as Manager
from pivot_data
pivot(max(emp_name) for job_name in ('Sales','Exec','Sec','Manager'))

SALES    EXEC    SEC    MANAGER
-------------------------------
                Roger    
        Scott        
        John        
Joe            
Steve            
        Paul        
                        Pete 

或者,如果这对你来说还不够,那么这个PL / SQL会做你想要的。我在11g上测试它并且我相当确定它可以与10g et 9i一起使用但是我不能保证任何DB2或者PostGre:

declare
    cursor C1 is 
    select 'Joe' as emp_name,'Sales' as job_name from dual union all
    select 'Steve','Sales'    from dual union all
    select 'Paul','Exec'     from dual union all
    select 'Pete','Manager'  from dual union all
    select 'John','Exec'     from dual union all
    select 'Roger','Sec'      from dual union all
    select 'Scott','Exec'     from dual;
    varray_sales dbms_sql.varchar2_table;
    varray_exec dbms_sql.varchar2_table;
    varray_manager dbms_sql.varchar2_table;
    varray_sec dbms_sql.varchar2_table;
    i_sales number := 0;
    i_exec number := 0;
    i_manager number := 0;
    i_sec number := 0;
    n_line_aextr number;
    colwidth number := 30;
    line varchar2(120);
    function max_de_deux (i number,x number) return number is
    begin
        return case when i > x then i else x end;
    end;
begin
    dbms_output.enable(120);
    for l1 in c1 loop
        if L1.job_name = 'Sales' then
            i_sales := i_sales+1;
            varray_sales(i_sales) := L1.emp_name; 
        elsif L1.job_name = 'Exec' then
            i_exec := i_exec+1;
            varray_exec(i_exec) := L1.emp_name;
        elsif L1.job_name = 'Manager' then
            i_Manager := i_Manager+1;
            varray_manager(i_Manager) := L1.emp_name;
        elsif L1.job_name = 'Sec' then
            i_sec := i_sec+1;
            varray_sec(i_sec) := L1.emp_name;
        end if;
    end loop;
    dbms_output.put_line(rpad('Sales',colwidth,' ')||rpad('Exec',colwidth,' ')||rpad('Manager',colwidth,' ')
                              ||rpad('Sec',colwidth,' '));
    dbms_output.put_line(rpad('-',colwidth,'-')||rpad('-',colwidth,'-')||rpad('-',colwidth,'-')
                              ||rpad('-',colwidth,'-'));
    n_line_aextr := max_de_deux(i_manager,max_de_deux(i_sec,max_de_deux(i_sales,i_exec)));

    for l in 1..n_line_aextr loop
        line := '';
        if l <= i_sales then
            line := line || rpad(varray_sales(l),colwidth,' ');
        else 
            line := line || rpad(' ',colwidth,' ');
        end if;
        if l <= i_exec then
            line := line || rpad(varray_exec(l),colwidth,' ');
        else 
            line := line || rpad(' ',colwidth,' ');
        end if;
        if l <= i_manager then
            line := line || rpad(varray_manager(l),colwidth,' ');
        else 
            line := line || rpad(' ',colwidth,' ');
        end if;
        if l <= i_sec then
            line := line || rpad(varray_sec(l),colwidth,' ');
        else 
            line := line || rpad(' ',colwidth,' ');
        end if;
        dbms_output.put_line(line);
    end loop;                                  

end;



Sales          Exec           Manager        Sec            
------------------------------------------------------------
Joe            Paul           Pete           Roger          
Steve          John                                         
               Scott