zoukankan      html  css  js  c++  java
  • SQL Cookbook—数字、日期

    1、计算不包含最大值和最小值的均值
    2、把字母数字串转换为数值
    3、更改累计和中的值–显示存款或取款后的值
    4、加减日、月、年
    5、计算两个日期之间的天数
    6、确定两个日期之间的工作日数目
    表EMP中,计算BLAKE和JONES的hiredate(聘用日期)之间的工作日数(除去星期六、星期天)
    7、确定两个日期之间的月份数或年数
    例如:EMP表中,求第一个员工和最后一个员工之间相差的月份数,以及这些月折合的年数
    8、确定两个日期之间的秒、分、小时数
    例如:EMP表中,求ALLEN和WARD的hiredate(聘用日期)之间相差的时间,分别用秒、分、小时表示
    9、计算一年中周内各日期的次数
    10、确定当前记录和下一条记录之间相差的天数
    11、确定一年是否为闰年
    12、确定一年内的天数
    13、从日期中提取时间的各个部分
    14、确定某个月的第一天和最后一天
    15、列出当年中的所有所于星期五的日期
    16、确定某月内第一个和最后一个“周内某天”的日期
    例如:找出当前月的第一个星期一及最后一个星期一的日期 next_day下一个星期几
    17、列出一年中每个季度的开始日期和结束日期
    18、确定某个给定季度的开始日期和结束日期
    19、填充丢失的日期
    –为给定范围内的每个日期(每个月、周或年)生成一行信息,这样的行集通常用于生成综合报告。
    –例如,计算每年内每个月聘用的员工数。检查已聘用的所有员工的聘用日期,其范围是 1980-1983
    –现在,要确定1980-1983年间每个月聘用的员工数。如有哪个月没有聘用,则显示为0个
    20、按照给定的时间单位进行查找
    –问题:查找与给定月份、星期几或其他时间单位相匹配的日期。
    –例如:找到2月份和12月份聘用的所有员工或者查找星期二聘用的所有员工
    21、使用日期的特殊部分比较记录
    –问题:查找聘用日期月份和周内日期都相同的员工。例如,如果在1988年3月10日星期一聘用了某了员工,
    –而在2001年3月2日星期一聘用了另一个员工,那么,由于二者的聘用日期都在星期一,而且月份名一致,则可以认为他们相匹配
    22、识别重叠的日期范围
    –问题:查找员工在老工程结束之前就开始新工作的所有实例 当结束那天正好接了另一个项目也算
    –一个开始时间在 另一行记录的开始时间和结束时间之间

    1、计算不包含最大值和最小值的均值
    SELECT (SUM(ID)-MAX(ID)-MIN(ID))/(COUNT(1)-2) FROM tb_dict

    2、把字母数字串转换为数值
    SELECT REPLACE(TRANSLATE(LOWER('adc12s3as'),
                             LOWER('abcdefghijklmnopqrstuvwxyz'),
                             RPAD('z', 24, 'z')),
                   'z',
                   '')
    FROM DUAL

    3、更改累计和中的值–显示存款或取款后的值
    with tmp as (
    select 1 tid,100 atm,'存款' trx from dual union all
    select 2 tid,100 atm,'存款' trx from dual union all
    select 3 tid,50  atm,'取款' trx from dual union all
    select 4 tid,100 atm,'存款' trx from dual union all
    select 5 tid,200 atm,'取款' trx from dual union all
    select 6 tid,50  atm,'取款' trx from dual
    )
    select trx,atm,sum(decode(trx,'存款',atm,-atm)) over (order by tid) balance from tmp

    4、加减日、月、年
    SELECT HIREDATE,
           HIREDATE – 5 AS HD_MINUS_5D,–减日
           HIREDATE + 5 AS HD_PLUS_5D,–加日
           ADD_MONTHS(HIREDATE, -5) AS HD_MINUS_5M,–减月
           ADD_MONTHS(HIREDATE, 5) AS HD_PLUS_5M,–加月
           ADD_MONTHS(HIREDATE, -5 * 12) AS HD_MINUS_5Y,–减年
           ADD_MONTHS(HIREDATE, 5 * 12) AS HD_PLUS_5Y–加年
      FROM EMP
     WHERE DEPTNO = 10

    5、计算两个日期之间的天数
    SELECT to_date('2012-10-22', 'yyyy-mm-dd') – to_date('2012-9-22', 'yyyy-mm-dd') FROM dual;

    6、确定两个日期之间的工作日数目
    表EMP中,计算BLAKE和JONES的hiredate(聘用日期)之间的工作日数(除去星期六、星期天)
    步骤:
    1)、建立索引表
    create table t500(
     id number(3)
    )
    2)、插入索引数据
    declare
       v_index number(3);
    begin
       for v_index in 1..500 loop
     insert into t500 values(v_index);
       end loop;
    end;
    3)、查询语句ss
    SELECT SUM(CASE
                 WHEN TO_CHAR(JONES_HIREDATE + T500.ID – 1, 'DY') IN('星期六', '星期日') THEN 0 ELSE 1
               END) AS DAYS
      FROM (SELECT MAX(CASE WHEN ENAME = 'BLAKE' THEN HIREDATE END) AS BLAKE_HIREDATE,
                   MAX(CASE WHEN ENAME = 'JONES' THEN HIREDATE END) AS JONES_HIREDATE
             FROM EMP
             WHERE ENAME IN ('BLAKE', 'JONES')) X,
             T500
     WHERE T500.ID <= BLAKE_HIREDATE – JONES_HIREDATE + 1

    7、确定两个日期之间的月份数或年数
    例如:EMP表中,求第一个员工和最后一个员工之间相差的月份数,以及这些月折合的年数
    SELECT MONTHS_BETWEEN(MAX_HIREDATE, MIN_HIREDATE),
           MONTHS_BETWEEN(MAX_HIREDATE, MIN_HIREDATE) / 12
      FROM (SELECT MIN(HIREDATE) MIN_HIREDATE, MAX(HIREDATE) MAX_HIREDATE
              FROM EMP)

    8、确定两个日期之间的秒、分、小时数
    例如:EMP表中,求ALLEN和WARD的hiredate(聘用日期)之间相差的时间,分别用秒、分、小时表示
    select dy*24 as hr, dy*24*60 as min, dy*24*60*60 as sec
    from (select (max(case when ename='WARD' then hiredate end)-max(case when ename='ALLEN' then hiredate end)) as dy from emp)

    9、计算一年中周内各日期的次数
    SELECT TO_CHAR(TRUNC(SYSDATE, 'y') + ROWNUM – 1, 'DY'), COUNT(*)
      FROM T500
     WHERE ROWNUM <= ADD_MONTHS(TRUNC(SYSDATE, 'y'), 12) – TRUNC(SYSDATE, 'y')
     GROUP BY TO_CHAR(TRUNC(SYSDATE, 'y') + ROWNUM – 1, 'DY')

    10、确定当前记录和下一条记录之间相差的天数
    SELECT ENAME, HIREDATE, NEXT_HD, NEXT_HD – HIREDATE DIFF
      FROM (SELECT DEPTNO,
                   ENAME,
                   HIREDATE,
                   LEAD(HIREDATE) OVER(ORDER BY HIREDATE) NEXT_HD
              FROM EMP)
     WHERE DEPTNO = 10

    11、确定一年是否为闰年
    此处采用了最简单的方案,检查2月最后一天,如果是29,则当年就为闰年,即此处的关键是得到2月的最后一天
    select to_char(last_day(add_months(trunc(sysdate, 'y'), 1)),'DD') from dual

    12、确定一年内的天数
    select add_months(trunc(sysdate, 'y'), 12)-trunc(sysdate, 'y') from dual

    13、从日期中提取时间的各个部分
    SELECT TO_CHAR(SYSDATE, 'hh24') HOUR,
           TO_CHAR(SYSDATE, 'mi') MIN,
           TO_CHAR(SYSDATE, 'ss') SEC,
           TO_CHAR(SYSDATE, 'dd') DAY,
           TO_CHAR(SYSDATE, 'mm') MONTH,
           TO_CHAR(SYSDATE, 'yyyy') YEAR
      FROM DUAL

    14、确定某个月的第一天和最后一天
    SELECT TRUNC(SYSDATE, 'mm') FIRSTDAY, LAST_DAY(SYSDATE) LASTDAY FROM DUAL

    15、列出当年中的所有所于星期五的日期
    with tmp_a as(
         –获取每一天
         select level num,trunc(sysdate,'y')+level-1 everyday from dual
                connect by level <= add_months(trunc(sysdate,'yyyy'),12)-trunc(sysdate,'y'))
    select num,everyday,to_char(everyday,'day')
    from tmp_a
    where to_char(everyday,'day') = '星期五'

    16、确定某月内第一个和最后一个“周内某天”的日期
    例如:找出当前月的第一个星期一及最后一个星期一的日期 next_day下一个星期几
    –方法一
    with tmp_a as (
         select level num,trunc(sysdate,'mm')+level-1 everyday from dual
                connect by level <= last_day(sysdate)-trunc(sysdate,'mm')+1)
    select min(everyday) 第一个星期一,
           max(everyday) 最后一个星期一 from tmp_a
    where to_char(everyday,'day') = '星期一'
    –方法二
    select next_day(trunc(sysdate,'mm')-1,'星期一'),
           next_day(last_day(trunc(sysdate,'mm')),'星期一')-7
    from dual

    17、列出一年中每个季度的开始日期和结束日期
    with tmp_a as(
    select ddate,to_char(ddate,'q') jidu from (
    select level,trunc(sysdate,'y')+level-1 ddate from dual
    connect by level <= add_months(trunc(sysdate,'y'),12)-trunc(sysdate,'y'))
    )select jidu 季度,min(ddate) 开始日期,max(ddate) 结束日期 from tmp_a
    group by jidu

    18、确定某个给定季度的开始日期和结束日期
    –方法一
    with tmp_a as(
    select ddate,to_char(ddate,'q') jidu from (
    select level,trunc(sysdate,'y')+level-1 ddate from dual
    connect by level <= add_months(trunc(sysdate,'y'),12)-trunc(sysdate,'y'))
    )
    select min(ddate),max(ddate) from tmp_a
    where jidu = '4'
    –方法二
    select jidu,add_months(ddate,-2) 开始日期,last_day(ddate) 结束日期 from (
    select jidu,to_date(ye||lpad(mon,2,'0'),'yyyymm') ddate from (
    select jidu,substr(jidu,1,4) ye,mod(jidu,10)*3 mon from (
    select 20081 jidu from dual union all
    select 20082 from dual union all
    select 20083 from dual union all
    select 20084 from dual
    )))

    19、填充丢失的日期
    –为给定范围内的每个日期(每个月、周或年)生成一行信息,这样的行集通常用于生成综合报告。
    –例如,计算每年内每个月聘用的员工数。检查已聘用的所有员工的聘用日期,其范围是 1980-1983
    –现在,要确定1980-1983年间每个月聘用的员工数。如有哪个月没有聘用,则显示为0个
    with tmp_a as(
    select 'aa' tno,to_date('19800506','yyyymmdd') hiredate from dual union all
    select 'bb' tno,to_date('19830701','yyyymmdd') hiredate from dual union all
    select 'cc' tno,to_date('19860702','yyyymmdd') hiredate from dual union all
    select 'dd' tno,to_date('19810510','yyyymmdd') hiredate from dual union all
    select 'ee' tno,to_date('19820503','yyyymmdd') hiredate from dual union all
    select 'gg' tno,to_date('19820504','yyyymmdd') hiredate from dual union all
    select 'ff' tno,to_date('19821015','yyyymmdd') hiredate from dual
    )
    select sta,sum(cnt) cnts,count(hiredate) from (–聚合函数count()不会计算为空的列,所以不必把null转换,在下面一层就可以求出来
    select sta,tno,hiredate,decode(tno,null,0,1) cnt from (
    select level,add_months(trunc(min_date,'y'),level-1) sta from (
        select min(hiredate) min_date,max(hiredate) max_date from tmp_a
    )
    connect by level <= months_between(add_months(trunc(max_date,'y'),12),trunc(min_date,'y')) ) t
    left join tmp_a on sta = trunc(hiredate,'mm')
    )group by sta
    order by sta

    20、按照给定的时间单位进行查找
    –问题:查找与给定月份、星期几或其他时间单位相匹配的日期。
    –例如:找到2月份和12月份聘用的所有员工或者查找星期二聘用的所有员工
    with tmp_a as(
    select 'aa' tno,to_date('19800506','yyyymmdd') hiredate from dual union all
    select 'bb' tno,to_date('19830701','yyyymmdd') hiredate from dual union all
    select 'cc' tno,to_date('19860702','yyyymmdd') hiredate from dual union all
    select 'dd' tno,to_date('19810510','yyyymmdd') hiredate from dual union all
    select 'ee' tno,to_date('19820503','yyyymmdd') hiredate from dual union all
    select 'gg' tno,to_date('19820504','yyyymmdd') hiredate from dual union all
    select 'ff' tno,to_date('19821015','yyyymmdd') hiredate from dual
    )
    select tno,hiredate,to_char(hiredate,'day'),to_char(hiredate,'mm') from tmp_a
    where to_char(hiredate,'day') = '星期二' or to_char(hiredate,'mm') in('07','05')

    21、使用日期的特殊部分比较记录
    –问题:查找聘用日期月份和周内日期都相同的员工。例如,如果在1988年3月10日星期一聘用了某了员工,
    –而在2001年3月2日星期一聘用了另一个员工,那么,由于二者的聘用日期都在星期一,而且月份名一致,则可以认为他们相匹配
    with tmp_a as(
    select tno,hiredate,to_char(hiredate,'day') xingqi,to_char(hiredate,'mm') mon from (
    select 'aa' tno,to_date('19800506','yyyymmdd') hiredate from dual union all
    select 'bb' tno,to_date('19830701','yyyymmdd') hiredate from dual union all
    select 'cc' tno,to_date('19860702','yyyymmdd') hiredate from dual union all
    select 'dd' tno,to_date('19810510','yyyymmdd') hiredate from dual union all
    select 'ee' tno,to_date('19820503','yyyymmdd') hiredate from dual union all
    select 'tt' tno,to_date('20090512','yyyymmdd') hiredate from dual union all
    select 'gg' tno,to_date('19820504','yyyymmdd') hiredate from dual union all
    select 'ff' tno,to_date('19821015','yyyymmdd') hiredate from dual)
    )
    select * from tmp_a x,tmp_a y
    where x.xingqi = y.xingqi and x.mon = y.mon and x.tno > y.tno

    22、识别重叠的日期范围
    –问题:查找员工在老工程结束之前就开始新工作的所有实例 当结束那天正好接了另一个项目也算
    –一个开始时间在 另一行记录的开始时间和结束时间之间
    –方法一
    with tmp_a as(
    select 7782 empno,'clark' ename,1 proj_id,to_date('20050616','yyyymmdd') proj_start,to_date('20050618','yyyymmdd') proj_end from dual union all
    select 7782 empno,'clark' ename,4 proj_id,to_date('20050619','yyyymmdd') proj_start,to_date('20050624','yyyymmdd') proj_end from dual union all
    select 7782 empno,'clark' ename,7 proj_id,to_date('20050622','yyyymmdd') proj_start,to_date('20050625','yyyymmdd') proj_end from dual union all
    select 7782 empno,'clark' ename,10 proj_id,to_date('20050625','yyyymmdd') proj_start,to_date('20050628','yyyymmdd') proj_end from dual union all
    select 7782 empno,'clark' ename,13 proj_id,to_date('20050628','yyyymmdd') proj_start,to_date('20050702','yyyymmdd') proj_end from dual union all
    select 7839 empno,'king' ename,2 proj_id,to_date('20050617','yyyymmdd') proj_start,to_date('20050621','yyyymmdd') proj_end from dual union all
    select 7839 empno,'king' ename,8 proj_id,to_date('20050623','yyyymmdd') proj_start,to_date('20050625','yyyymmdd') proj_end from dual union all
    select 7839 empno,'king' ename,14 proj_id,to_date('20050629','yyyymmdd') proj_start,to_date('20050630','yyyymmdd') proj_end from dual union all
    select 7839 empno,'king' ename,11 proj_id,to_date('20050626','yyyymmdd') proj_start,to_date('20050627','yyyymmdd') proj_end from dual union all
    select 7839 empno,'king' ename,5 proj_id,to_date('20050620','yyyymmdd') proj_start,to_date('20050624','yyyymmdd') proj_end from dual union all
    select 7934 empno,'miller' ename,3 proj_id,to_date('20050618','yyyymmdd') proj_start,to_date('20050622','yyyymmdd') proj_end from dual union all
    select 7934 empno,'miller' ename,12 proj_id,to_date('20050627','yyyymmdd') proj_start,to_date('20050628','yyyymmdd') proj_end from dual union all
    select 7934 empno,'miller' ename,15 proj_id,to_date('20050630','yyyymmdd') proj_start,to_date('20050703','yyyymmdd') proj_end from dual union all
    select 7934 empno,'miller' ename,9 proj_id,to_date('20050624','yyyymmdd') proj_start,to_date('20050627','yyyymmdd') proj_end from dual union all
    select 7934 empno,'miller' ename,6 proj_id,to_date('20050621','yyyymmdd') proj_start,to_date('20050623','yyyymmdd') proj_end from dual
    )select * from tmp_a x,tmp_a y
    where x.ename = y.ename and x.proj_start <= y.proj_end and x.proj_id <> y.proj_id
    and x.proj_start >= y.proj_start

    –方法二
    –从1开始找出不连续的值 用联接 先产生一批连续的值,与所求表去联接则可
    with tmp_a as(
    select level base from dual
    connect by level <= 100000
    )select * from tmp_a x,(
    select 2 num from dual union all
    select 5 num from dual union all
    select 6 num from dual union all
    select 9 num from dual union all
    select 12 num from dual
    )y where x.base = y.num(+)
    and y.num is null
    order by x.base

  • 相关阅读:
    linux内核中的subsys_initcall是干什么的?
    linux内核中的MFD子系统
    linux内核中有哪些子系统(框架)呢?
    软件架构师书籍
    求最大公约数和最小公倍数
    写一个函数判断字符串中"{"与"}","["与"]","("与")"匹配,"{"必须在"}"前面,"["必须在"]"前面,"("必须在")"前面,可以嵌套
    请用程序写出冒泡排序算法,并做相应改进使得排序效率更高
    50个必备的实用jQuery代码段+ 可以直接拿来用的15个jQuery代码片段
    js同比例缩放图片
    oracle 10g函数大全--其他函数
  • 原文地址:https://www.cnblogs.com/linjiqin/p/3152572.html
Copyright © 2011-2022 走看看