oracle 3个实用统计sql场景

我们使用oracle做一些统计的时候,时常碰到如下场景:

1.竖列转横列

2.分组并合并某列作为结果集

3.分组排序取首条记录

我们使用一个简化的业务场景,来展示这三个场景如何使用sql来解决。

业务场景:一张表记录着员工的出勤记录

业务需求:(对应上面的三个场景)

1.统计员工某年的每月出勤记录数

2.查询每个人的出勤记录

3.获得每个员工第一天上班的出勤记录

首先我们先创建测试数据表和测试数据

Sql代码  

  1. --创建考勤记录表
  2. CREATE TABLE T_ATTENDANCE_LOG
  3. (
  4. ID_ VARCHAR(36),
  5. USERNAME_ VARCHAR(255),
  6. LOGDATE_ VARCHAR(100)
  7. )
  8. --初始化一些测试数据
  9. insert into T_ATTENDANCE_LOG (ID_,USERNAME_,LOGDATE_) VALUES (‘1‘,‘张三‘,‘2014-02-01‘);
  10. insert into T_ATTENDANCE_LOG (ID_,USERNAME_,LOGDATE_) VALUES (‘2‘,‘张三‘,‘2014-02-02‘);
  11. insert into T_ATTENDANCE_LOG (ID_,USERNAME_,LOGDATE_) VALUES (‘3‘,‘张三‘,‘2014-02-03‘);
  12. insert into T_ATTENDANCE_LOG (ID_,USERNAME_,LOGDATE_) VALUES (‘4‘,‘张三‘,‘2014-02-04‘);
  13. insert into T_ATTENDANCE_LOG (ID_,USERNAME_,LOGDATE_) VALUES (‘5‘,‘张三‘,‘2014-02-05‘);
  14. insert into T_ATTENDANCE_LOG (ID_,USERNAME_,LOGDATE_) VALUES (‘6‘,‘张三‘,‘2014-02-06‘);
  15. insert into T_ATTENDANCE_LOG (ID_,USERNAME_,LOGDATE_) VALUES (‘11‘,‘李四‘,‘2014-03-01‘);
  16. insert into T_ATTENDANCE_LOG (ID_,USERNAME_,LOGDATE_) VALUES (‘12‘,‘李四‘,‘2014-04-01‘);
  17. insert into T_ATTENDANCE_LOG (ID_,USERNAME_,LOGDATE_) VALUES (‘13‘,‘李四‘,‘2014-05-01‘);
  18. insert into T_ATTENDANCE_LOG (ID_,USERNAME_,LOGDATE_) VALUES (‘21‘,‘王五‘,‘2014-02-15‘);
  19. insert into T_ATTENDANCE_LOG (ID_,USERNAME_,LOGDATE_) VALUES (‘22‘,‘王五‘,‘2014-03-15‘);
  20. --查询
  21. SELECT T.*,T.ROWID FROM  T_ATTENDANCE_LOG T;

结果:

1.统计员工2014年的每月出勤情况

Sql代码  

  1. with sql1 as
  2. (
  3. select USERNAME_,substr(LOGDATE_,0,7) as a,count(LOGDATE_) as b from T_ATTENDANCE_LOG
  4. group by USERNAME_,substr(LOGDATE_,0,7)
  5. )
  6. select USERNAME_,
  7. sum(case A when ‘2014-01‘ then B end) 一月,
  8. sum(case A when ‘2014-02‘ then B end) 二月,
  9. sum(case A when ‘2014-03‘ then B end) 三月,
  10. sum(case A when ‘2014-04‘ then B end) 四月,
  11. sum(case A when ‘2014-05‘ then B end) 五月,
  12. sum(case A  when ‘2014-06‘ then B  end) 六月,
  13. sum(case A  when ‘2014-07‘ then B  end) 七月,
  14. sum(case A  when ‘2014-08‘ then B  end) 八月,
  15. sum(case A  when ‘2014-09‘ then B  end) 九月,
  16. sum(case A  when ‘2014-10‘ then B  end) 十月,
  17. sum(case A  when ‘2014-11‘ then B  end) 十一月,
  18. sum(case A  when ‘2014-12‘ then B  end) 十二月
  19. from sql1  group by USERNAME_

这里用到“sql统计利器”--with。

结果:

2.查询每个人的出勤记录

Sql代码  

  1. select USERNAME_ as 员工,wmsys.wm_concat(LOGDATE_) as 出勤记录 from T_ATTENDANCE_LOG t group by  USERNAME_

结果:

但是我们发现这个统计出来的结果是乱序,改造一下

Sql代码  

  1. select USERNAME_ as 员工, max(r) as 出勤记录 from (
  2. select USERNAME_,wmsys.wm_concat(LOGDATE_) OVER(PARTITION BY USERNAME_ ORDER BY LOGDATE_) r
  3. from T_ATTENDANCE_LOG t
  4. )group by USERNAME_

改造结果:

3.获得每个员工第一天上班的出勤记录

Sql代码  

  1. SELECT * FROM
  2. (
  3. --分组排序加序号
  4. select USERNAME_,LOGDATE_,ROW_NUMBER() OVER(PARTITION BY USERNAME_ ORDER BY LOGDATE_) r
  5. from T_ATTENDANCE_LOG t
  6. group by USERNAME_,LOGDATE_
  7. ) where R=1

结果:

时间: 2024-10-30 02:53:39

oracle 3个实用统计sql场景的相关文章

oracle 普通业务数据统计sql

-- 字符串分割示例 SELECT REGEXP_SUBSTR('17,20,23', '[^,]+', 1, LEVEL, 'i') AS STR FROM DUAL CONNECT BY LEVEL <= LENGTH('17,20,23') - LENGTH(REGEXP_REPLACE('17,20,23', ',', ''))+1; CREATE TABLE tm_change( ID NUMBER, transit_zno VARCHAR2(10), src VARCHAR2(100

Oracle EBS-SQL (PO-16):检查采购订单完成情况统计.sql

select         e.FULL_NAME                                                     采购员,         sum(plla.quantity-plla.QUANTITY_CANCELLED)  订购数量,         sum(plla.Quantity_Received)                           完成数量 ,         round(SUM(plla.Quantity_Receive

Oracle按时间段分组统计

想要按时间段分组查询,首先要了解level,connect by,oracle时间的加减. 关于level这里不多说,我只写出一个查询语句: ----level 是一个伪例 select level from dual connect by level <=10 ---结果: 1 2 3 4 5 6 7 8 9 10 关于connect by可以看 http://www.cnblogs.com/johnnyking39/articles/1155497.html oracle时间的加减看看试一下

ORACLE将执行过的SQL语句存放在内存的共享池

Oracle SQL性能优化深入浅出 ORACLE将执行过的SQL语句存放在内存的共享池(shared buffer pool)中,可以被所有的数据库用户共享.当你执行一个SQL语句(有时被称为一个游标)时,如果它和之前的执行过的语句完全相同,ORACLE就能很快获得已经被解析的语句以及最好的执行路径. 这个功能大大地提高了SQL的执行性能并节省了内存的使用. 为了不重复解析相同的SQL语句,在第一次解析之后,Oracle将SQL语句存放在内存中.这块位于系统全局区域SGA(systemglob

SQL优化:一些简单的又实用的SQL优化方案【转】

面试过程中,面试官有极高的频率会问道数据库的优化,SQL语句的优化,网上关于SQL优化的教程很多,但是鱼目混杂,显得有些杂乱不堪.近日有空整理了一下,写出来跟大家分享一下,其中有错误和不足的地方,还请大家纠正补充. 本文主要来自于互联网,进行内容的筛选优化再度整合而来,感觉好的话推荐给更多的人,让更多的人看到.纠正以及补充,鄙人文笔不好,也请大家多多海涵. 1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where

Oracle性能优化之统计信息管理_超越OCP精通Oracle视频教程培训32

Oracle性能优化之统计信息管理_超越OCP精通Oracle视频教程培训32 本课程介绍: Oracle视频教程,风哥本套oracle教程培训<<Oracle数据库性能优化培训教程>>的第2/10套:Oracle性能优化之执行计划管理.主要学习Oracle性能优化,统计信息的作用与查看,收集统计信息的方法之analyze,收集统计信息的方法之DBMS_STATS,收集统计信息的方法之数据库,收集统计信息的方法之用户,收集统计信息的方法之表,收集统计信息的方法之索引,收集统计信息的

【Oracle 常用查询】oracle表空间使用率统计查询

参考1 --查询表空间使用情况 SELECT Upper(F.TABLESPACE_NAME) "表空间名", D.TOT_GROOTTE_MB "表空间大小(M)", D.TOT_GROOTTE_MB - F.TOTAL_BYTES "已使用空间(M)", To_char(Round(( D.TOT_GROOTTE_MB - F.TOTAL_BYTES ) / D.TOT_GROOTTE_MB * 100, 2), '990.99') || '

Oracle数据库之开发PL/SQL子程序和包

Oracle数据库之开发PL/SQL子程序和包 PL/SQL块分为匿名块与命名块,命名块又包含子程序.包和触发器. 过程和函数统称为PL/SQL子程序,我们可以将商业逻辑.企业规则写成过程或函数保存到数据库中,以便共享. 过程和函数均存储在数据库中,并通过参数与其调用者交换信息.过程和函数的唯一区别是函数总向调用者返回数据,而过程不返回数据. 1. 存储过程概念 存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL语句集,存储在数据库中.经过第一次编译后

oracle数据库性能影响之Sql parse

1,Sql parse的种类 Sql parse又通常分为硬解析和软解析,当sql第一次执行的时候,会发生硬解析,之后的执行如果在shared pool中能找到就是软解析.因此,为提高数据性能,尽可能的让每次执行的SQL在shared pool找到. 2,SQL在哪些情况下会发送硬解析? 1)统计信息改变  2)Sql中的表上有做ddl操作,包括grant和revoke. 3)执行计划被踢出shared pool 4)开启了trace 5)绑定变量长度变化 6)启用outlin