ORACLE 一些日期运算应用


-- 加减日、月、年

SELECT 
    sys_time AS 行为日期,
    sys_time - 5 AS 减5天,
    sys_time + 5 AS 加5天,
    ADD_MONTHS (sys_time ,- 5) AS 减5个月,
    ADD_MONTHS (sys_time ,5) AS 加5个月,
    ADD_MONTHS (sys_time ,- 5 * 12) AS 减5年,
    ADD_MONTHS (sys_time ,5 * 12) AS 加5年
FROM
    DBANALYSIS.TEST_USERS
where rownum < 100;

ORACLE 一些日期运算应用_第1张图片

 

-- 加减时、分、秒
-- date可以直接加减天数,那么1/24就是一小时,分钟与秒的加减类似

SELECT
    sys_time AS 行为日期,
    sys_time - 5 / 24 / 60 / 60 AS 减5秒,
    sys_time + 5 / 24 / 60 / 60 AS 加5秒,
    sys_time - 5 / 24 / 60      AS 减5分钟,
    sys_time + 5 / 24 / 60      AS 加5分钟,
    sys_time - 5 / 24           AS 减5小时,
    sys_time + 5 / 24           AS 加5小时
FROM
    DBANALYSIS.TEST_USERS
where rownum < 100
ORDER BY    sys_time;

ORACLE 一些日期运算应用_第2张图片

-- 时间间隔之时、分、秒
-- 两个date相减,得到的就是天数,乘以24就是小时,以此类推,可以计算出秒

SELECT
    间隔天数,
    间隔天数 * 24 AS 间隔小时,
    间隔天数 * 24 * 60 AS 间隔分钟,
    间隔天数 * 24 * 60 * 60 AS 间隔秒
FROM
    (
        SELECT
            round(MAX (sys_time) - MIN (sys_time),0) AS 间隔天数   -- 天数取整
        FROM
            DBANALYSIS.TEST_USERS
    );



 

-- 时间间隔之日、月、年
-- 加减月份用函数add_months,而计算月份间隔要用函数months_between,间隔年为间隔月除以12即可
-- 注意months_between的两个时间参数前后位置颠倒会影响计算结果的正负
-- 当第一个日期大于第二个日期参数时,结果为正
-- 当第一个日期小于第二个日期参数时,结果为负
-- 当第一个日期等于第二个日期参数时,结果为0

SELECT
    (max_date - min_date) 间隔天,
    MONTHS_BETWEEN (max_date, min_date) 正间隔月,
    MONTHS_BETWEEN (min_date, max_date) 负间隔月,
    MONTHS_BETWEEN (min_date, min_date) 零间隔月,
    MONTHS_BETWEEN (max_date, min_date) / 12 正间隔年,
    MONTHS_BETWEEN (min_date, max_date) / 12 负间隔年
FROM
    (
        SELECT
            MAX (sys_time) max_date,
            MIN (sys_time) min_date
        FROM
            DBANALYSIS.TEST_USERS
    );


-- 确定两个日期之间的工作天数 WORKING DAYS
-- 1. 先将两个日期间的日期全部罗列出来,使用CONNECT BY LEVEL
-- 2. 用to_char函数转换为星期几,‘DY’转化为周几,'NLS_DATE_LANGUAGE'设置语言格式
-- 'NLS_DATE_LANGUAGE = American'
-- 'NLS_DATE_LANGUAGE = ''SIMPLIFIED CHINESE''' 简体中文
-- 3. 对结果进行筛选,去除星期六、星期日的数据
-- 4. 对筛选后的日期进行数量统计

SELECT COUNT(*) 
FROM
(
SELECT DATE_LIST,TO_CHAR(DATE_LIST,'DY','NLS_DATE_LANGUAGE = American') AS DY
FROM 
(
    SELECT (min_date + LEVEL - 1) DATE_LIST
    from 
        (    SELECT    MAX(trunc(sys_time)) max_date, MIN(trunc(sys_time)) min_date
            FROM DBANALYSIS.TEST_USERS ) 
    CONNECT BY LEVEL <= max_date - min_date + 1
))
where DY not in ('SUN','SAT');   


-- 计算一年中周内各日期的次数,如本例计算2013年一共多少个星期一,星期二...
-- 此处使用with从句
/*
WITH从句在oracle9i及之后高版本中可用
从句就像构建了一些临时表,目的是改进复杂查询的性能
当子查询需要多次执行时,可以使用WITH从句,同样,在递归查询中使用效果也很好

With New_SQL_Query_name As
(
SQL query
)
Select * from New_SQL_Query_name;
执行顺序:
Step 1 :with从句中的sql query先执行
Step 2 : 第一步的执行结果临时存储,同New_SQL_Query_name关联
Step 3 : 主查询通过临时存储的New_SQL_Query_name最后执行
*/

-- 枚举法
WITH X0 AS 
    (SELECT TO_DATE('2013-01-01', 'yyyy-mm-dd') AS 年初    FROM DUAL),
    X1 AS 
    (SELECT 年初, add_months(年初,12) as 下年初    FROM X0),
    X2 AS 
    (SELECT 年初,下年初 - 年初 as 天数 FROM X1),
    X3 AS 
    (SELECT 年初 + (level - 1) AS 日期 FROM X2 CONNECT BY LEVEL <= 天数),
    x4 AS 
    (SELECT 日期, to_char(日期,'DY') AS 星期 FROM X3)
SELECT 星期,count(*) as 天数 FROM X4 GROUP BY 星期;

ORACLE 一些日期运算应用_第3张图片

-- 如果不想用枚举法,也可以直接取出年内各工作日的第一天和最后一天,然后除以7
-- next_day(date,char)的理解,它是指指定日期date之后的未来最近的一个日期 
-- 注意,char=1,未来第一个周日,char=2,未来第二个周一,注意不一定是下一个星期的
-- 下述写法中,next_day里面年初-1,是为了将年初第一天2013-01-01是周二的信息不丢失。不减去1,就直接查询到下个星期的周二了。
-- next_day中年底-8,这样+1天,+2天,加到1周都没有超出2013年12月31日,统计的都是全年的。

WITH X0 AS 
    (SELECT TO_DATE('2013-01-01','yyyy-mm-dd') AS 年初 FROM DUAL),
         X1 AS 
    (SELECT 年初,add_months(年初,12) AS 年底 FROM X0),
       X2 AS 
    (SELECT next_day(年初-1,level) D1,next_day(年底-8,level) D2 FROM X1    CONNECT BY LEVEL <=7)  
SELECT TO_CHAR(D1,'DY') AS 星期,((D2-D1)/7+1)天数 FROM X2 ORDER BY 2 DESC;
    

-- 确定当前记录和下一条记录之间相差的天数
-- 为了获得后一条数据、前一条数据的时间,可以使用lead(),lag()

SELECT
    ACTION_TIME,    next_actiontime,
    EXTRACT(SECOND    FROM(    next_actiontime - ACTION_TIME    )    ) TIME_GAP
FROM
    (
        SELECT
            ACTION_TIME,LEAD (ACTION_TIME) OVER (ORDER BY ACTION_TIME) next_actiontime
        FROM    DBANALYSIS.TEST_USERS
    );

ORACLE 一些日期运算应用_第4张图片

 参考书《oracle查询优化改写技巧与案例》

你可能感兴趣的:(Oracle,oracle,时间运算,数据库)