oracle 行转列

1.例子
— 查询 每个部门下面,每个工种的人数,

select t.deptno,t.job,count(*) as job_count_ from emp t group by t.deptno,t.job ;
-- case when 
select 
    t.deptno,
    sum(case when t.job='CLERK' then t.job_count_ else 0 end) as CLERK_COUNT_,
    sum(case when t.job='SALESMAN' then t.job_count_ else 0 end) as SALESMAN_COUNT_,
    sum(case when t.job='PRESIDENT' then t.job_count_ else 0 end) as PRESIDENT_COUNT_,
    sum(case when t.job='MANAGER' then t.job_count_ else 0 end) as MANAGER_COUNT_,
    sum(case when t.job='ANALYST' then t.job_count_ else 0 end) as ANALYST_COUNT_,
    sum(t.job_count_) as sum_count_
from (
  select t.deptno,t.job,count(*) as job_count_ from emp t group by t.deptno,t.job 
) t group by t.deptno order by t.deptno ;
--- decode
select 
    t.deptno,
    sum(decode(t.job,'CLERK',t.job_count_,0)) as CLERK_COUNT_,
    sum(decode(t.job,'SALESMAN',t.job_count_,0)) as SALESMAN_COUNT_,
    sum(decode(t.job,'PRESIDENT',t.job_count_,0)) as PRESIDENT_COUNT_,
    sum(decode(t.job,'MANAGER',t.job_count_,0)) as MANAGER_COUNT_,
    sum(decode(t.job,'ANALYST',t.job_count_,0)) as ANALYST_COUNT_,
    sum(t.job_count_) as sum_count_
from (
  select t.deptno,t.job,count(*) as job_count_ from emp t group by t.deptno,t.job 
) t group by t.deptno order by t.deptno;

—- 一个问题,当前的job 是固定,如果job是动态变化的怎么处理
2.case when
CASE sex

WHEN ‘1’ THEN ‘男’

WHEN ‘2’ THEN ‘女’

ELSE ‘其他’ END

3.Decode
含义解释:
decode(条件,值1,返回值1,值2,返回值2,…值n,返回值n,缺省值)

该函数的含义如下:
IF 条件=值1 THEN
    RETURN(翻译值1)
ELSIF 条件=值2 THEN
    RETURN(翻译值2)
    ……
ELSIF 条件=值n THEN
    RETURN(翻译值n)
ELSE
    RETURN(缺省值)
END IF
decode(字段或字段的运算,值1,值2,值3)
这个函数运行的结果是,当字段或字段的运算的值等于值1时,该函数返回值2,否则返回值3
当然值1,值2,值3也可以是表达式,这个函数使得某些sql语句简单了许多
4.扩展
Oracle存储过程使用动态SQL 有两种写法:用 DBMS_SQL 或 execute immediate,建议使用后者。
1. DDL和DML (注意DDL中可以用拼接字符串的方法用来create table或drop table,
在DML中,类似于insert则不可以直接用execute immediate中直接拼接的方法,必须用using传递参数)

declare   
    v_deptno dept.deptno%type;
    v_dname  dept.dname%type;
    v_loc    dept.loc%type;
    v_ins_str varchar2(500);
begin   
    v_deptno:=50;
    v_dname:='IT';   
    v_loc := 'SHANGHAI';   
    v_ins_str := 'insert into dept values(:1,:2,:3)';
    EXECUTE IMMEDIATE v_ins_str USING v_deptno,v_dname,v_loc;   
    commit;   
end;
declare
  v_col_name  varchar2(30) := 'ename';
  v_user_name varchar2(30);
  v_user_job  varchar2(30);
  v_sql_str   varchar2(500);
begin
    v_sql_str := 'select ' || v_col_name || ',job from emp where empno =:1';
    execute immediate v_sql_str into v_user_name, v_user_job using 7369 ;
    dbms_output.put_line('v_user_name:' || v_user_name || ',v_user_job:' ||v_user_job); 
end;
declare 
  type cur_ref_emp is ref cursor;
  deptJobRel   cur_ref_emp ;
  cursor cur_emp_ is select distinct job from emp;
  row_emp_ cur_emp_%rowtype;
  var_sql_str  varchar2(500);
  var_sql_str2 varchar2(500);
  var_sql_str3 varchar2(500) := ' select t.deptno,t.job,count(*) as job_count_ from emp t group by t.deptno,t.job ';
begin
  for row_emp_ in cur_emp_ loop
    var_sql_str2 := var_sql_str2 || ' sum(decode(t.job,''' || row_emp_.job ||
                    ''',t.job_count_,0)) as ' || row_emp_.job ||
                    '_COUNT_, ';
  end loop;

  var_sql_str := 'select t.deptno,' || var_sql_str2 ||
                 ' sum(t.job_count_) as sum_count_ from (' || var_sql_str3 ||
                 ') t group by t.deptno order by t.deptno ';

  open deptJobRel for var_sql_str;
end;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值