分享

Oracle行转列、列转行的Sql语句总结

 melodyjian 2018-12-06

实际上就是拆分字符串的问题,可以使用 substr、instr、regexp_substr函数方式

wm_concat函数:

函数wm_concat(列名),该函数可以把列值以","号分隔起来,并显示成一行

SELECT wm_concat(LAST_NAME) FROM PLCH_EMPLOYEES;

把结果里的逗号替换成"|"

  1. SELECT
  2. REPLACE(wm_concat(LAST_NAME),',','|') as lastnames
  3. FROM PLCH_EMPLOYEES;

按部门分组合并name

  1. SELECT DEPARTMENT_ID,wm_concat(LAST_NAME) as lastnames
  2. FROM PLCH_EMPLOYEES
  3. GROUP BY DEPARTMENT_ID;

懒人扩展用法:

我要写一个视图,类似"create or replace view as select 字段1,...字段50 from tablename" ,基表有50多个字段,要是靠手工写太麻烦了,有没有什么简便的方法? 当然有了,看我如果应用wm_concat来让这个需求变简单。查询结果如下:
  1. select
  2.   'CREATE OR REPLACE VIEW AS SELECT ' ||
  3.   WMSYS.WM_CONCAT(COLUMN_NAME) ||
  4.   ' FROM PLCH_EMPLOYEES ;' sqlstr
  5. from
  6.   user_tab_columns
  7. where
  8.   TABLE_NAME = 'PLCH_EMPLOYEES';


行列转换:

pivot


语法:

  1. SELECT ...
  2. FROM ...
  3. PIVOT [XML]
  4. ( pivot_clause
  5. pivot_for_clause
  6. pivot_in_clause )
  7. WHERE ...

pivot_clause: defines the columns to be aggregated (pivot is an aggregate operation);这个是指定我们的聚合函数

pivot_for_clause: defines the columns to be grouped and pivoted;指定我们需要将行转成列的字段

pivot_in_clause: defines the filter for the column(s) in the pivot_for_clause (i.e. the range of values to limit the results to). The aggregations for each value in the pivot_in_clause will be transposed into a separate column (where appropriate).对pivot_for_clause 指定的列进行过滤,只将指定的行转成列。

数据


查询每个部门有多少名员工赚的钱少于2500,以及有多少人多于或等于2500

  1. SELECT * FROM
  2. (SELECT DEPTNO , CASE when sal > 2500 then 'MORE' else 'LESS' end salary_category FROM EMP)
  3. PIVOT
  4. (COUNT(1) FOR salary_category IN ('LESS','MORE'))
  5. ;


查询每个部门每个job总工资

  1. select * from(
  2. SELECT DEPTNO , SAL,JOB FROM EMP
  3. )
  4. PIVOT (
  5. SUM(SAL) FOR JOB IN (
  6. 'CLERK' AS CLERK,
  7. 'MANAGER' AS MANAGER,
  8. 'SALESMAN' AS SALESMAN,
  9. 'PRESIDEN' AS PRESIDEN,
  10. 'ANALYST' AS ANALYST
  11. )
  12. );

查询每个部门每个job员工人数以及总工资

  1. select * from(
  2. SELECT DEPTNO , SAL,JOB FROM EMP
  3. )
  4. PIVOT (
  5. count(1) as cnt,SUM(SAL) as sals
  6. FOR JOB
  7. IN (
  8. 'CLERK' AS CLERK,
  9. 'MANAGER' AS MANAGER,
  10. 'SALESMAN' AS SALESMAN,
  11. 'PRESIDEN' AS PRESIDEN,
  12. 'ANALYST' AS ANALYST
  13. )
  14. );

查询depno为30的部门里面,job为SALESMAN,MANAGER,CLERK的员工各有多少人以及总工资为多少。

  1. select * from(
  2. SELECT DEPTNO , SAL,JOB FROM EMP
  3. )
  4. PIVOT (
  5. count(1) as cnt,SUM(SAL) as sals
  6. FOR (DEPTNO, JOB)
  7. IN (
  8. (30,'CLERK') AS dep30_CLERK,
  9. (30,'MANAGER') AS dep30_MANAGER,
  10. (30,'SALESMAN') AS dep30_SALESMAN
  11. )
  12. );

unpivot:

语法:

  1. SELECT ...
  2. FROM ...
  3. UNPIVOT [INCLUDE|EXCLUDE NULLS]
  4. ( unpivot_clause
  5. unpivot_for_clause
  6. unpivot_in_clause )
  7. WHERE ...



数据:pivoted_data


  1. SELECT *
  2. FROM pivoted_data
  3. UNPIVOT (
  4. deptsal --<-- unpivot_clause
  5. FOR saldesc --<-- unpivot_for_clause
  6. IN (d10_sal, d20_sal, d30_sal, d40_sal) --<-- unpivot_in_clause
  7. );

默认是不包含nulls的,我们通过命令处理nulls的结果

  1. SELECT *
  2. FROM pivoted_data
  3. UNPIVOT INCLUDE NULLS(
  4. deptsal --<-- unpivot_clause
  5. FOR saldesc --<-- unpivot_for_clause
  6. IN (d10_sal, d20_sal, d30_sal, d40_sal) --<-- unpivot_in_clause
  7. );

使用别名

  1. SELECT job,saldesc,deptsal
  2. FROM pivoted_data
  3. UNPIVOT (deptsal
  4. FOR saldesc IN (d10_sal AS 'SAL TOTAL FOR 10',
  5. d20_sal AS 'SAL TOTAL FOR 20',
  6. d30_sal AS 'SAL TOTAL FOR 30',
  7. d40_sal AS 'SAL TOTAL FOR 40'))
  8. ORDER BY job,saldesc;



    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多