oralce 日期 大全

来源:互联网 发布:省市区三级联动sql 编辑:程序博客网 时间:2024/05/18 03:51

http://blog.csdn.net/arui_email/article/details/11948065


[sql] view plain copy
 print?
  1. ORACLE日期函数大全!  
  2. 2009-03-12 14:16:10日期函数 Oracle PL/SQL Oracle的日期函数相信很多人都有过统计某些数据的经历,比如,要统计财务的情况,可能要按每年,每季度,每月,甚至每个星期来分别统计。那在oracle中应该怎么来写sql语句呢,这个时候Oracle的日期函数会给我们很多帮助。  
  3.   
  4. 常用日期型函数   
  5. 1。Sysdate 当前日期和时间  
  6. SQL> Select sysdate from dual;  
  7.   
  8. SYSDATE  
  9. ----------  
  10. 21-6月 -05  
  11.   
  12. 2。Last_day 本月最后一天   
  13. SQL> Select last_day(sysdate) from dual;  
  14.   
  15. LAST_DAY(S  
  16. ----------  
  17. 30-6月 -05  
  18.   
  19. 3。Add_months(d,n) 当前日期d后推n个月   
  20. 用于从一个日期值增加或减少一些月份   
  21. date_value:=add_months(date_value,number_of_months)  
  22.   
  23. SQL> Select add_months(sysdate,2) from dual;  
  24.   
  25. ADD_MONTHS  
  26. ----------  
  27. 21-8月 -05  
  28.   
  29. 4。Months_between(f,s) 日期f和s间相差月数   
  30. SQL> select months_between(sysdate,to_date('2005-11-12','yyyy-mm-dd'))from dual;  
  31.   
  32. MONTHS_BETWEEN(SYSDATE,TO_DATE('2005-11-12','YYYY-MM-DD'))  
  33. ----------------------------------------------------------  
  34.                                                  -4.6966741   
  35.   
  36. 5。NEXT_DAY(d, day_of_week)  
  37. 返回由"day_of_week"命名的,在变量"d"指定的日期之后的第一个工作日的日期。参数"day_of_week"必须为该星期中的某一天。  
  38. SQL> SELECT next_day(to_date('20050620','YYYYMMDD'),1) FROM dual;  
  39.   
  40. NEXT_DAY(T  
  41. ----------  
  42. 26-6月 -05  
  43.   
  44. 6。current_date()返回当前会话时区中的当前日期   
  45. date_value:=current_date   
  46. SQL> column sessiontimezone for a15   
  47. SQL> select sessiontimezone,current_date from dual;   
  48.   
  49. SESSIONTIMEZONE CURRENT_DA   
  50. --------------- ----------   
  51. +08:00           13-11月-03   
  52.     
  53. SQL> alter session set time_zone='-11:00' 2   /   
  54. 会话已更改。   
  55.     
  56. SQL> select sessiontimezone,current_timestamp from dual;   
  57.   
  58. SESSIONTIMEZONE CURRENT_TIMESTAMP   
  59. --------------- ------------------------------------   
  60. -11:00           12-11月-03 04.59.13.668000 下午 -11:00   
  61.   
  62. 7。current_timestamp()以timestamp with time zone数据类型返回当前会话时区中的当前日期  
  63. SQL> select current_timestamp from dual;  
  64.   
  65. CURRENT_TIMESTAMP  
  66. ---------------------------------------------------------------------------  
  67. 21-6月 -05 10.13.08.220589 上午 +08:00  
  68.   
  69. 8。dbtimezone()返回时区  
  70. SQL> select dbtimezone from dual;  
  71.   
  72. DBTIME  
  73. ------  
  74. -08:00  
  75.   
  76. 9。extract()找出日期或间隔值的字段值   
  77. date_value:=extract(date_field from [datetime_value|interval_value])   
  78. SQL> select extract(month from sysdate) "This Month" from dual;  
  79.   
  80. This Month  
  81. ----------  
  82.          6  
  83.   
  84. SQL> select extract(year from add_months(sysdate,36)) " Years" from dual;  
  85.   
  86.      Years  
  87. ----------  
  88.        2008  
  89.   
  90. 10。localtimestamp()返回会话中的日期和时间   
  91. SQL> select localtimestamp from dual;  
  92.   
  93. LOCALTIMESTAMP  
  94. ---------------------------------------------------------------------------  
  95. 21-6月 -05 10.18.15.855652 上午  
  96.   
  97. 常用日期数据格式(该段为摘抄)  
  98.   
  99. Y或YY或YYY 年的最后一位,两位或三位 Select to_char(sysdate,’YYY’) from dual; 002表示2002年   
  100. SYEAR或YEAR SYEAR使公元前的年份前加一负号 Select to_char(sysdate,’SYEAR’) from dual; -1112表示公元前111 2年   
  101. Q 季度,1~3月为第一季度 Select to_char(sysdate,’Q’) from dual; 2表示第二季度①   
  102. MM 月份数 Select to_char(sysdate,’MM’) from dual; 12表示12月   
  103. RM 月份的罗马表示 Select to_char(sysdate,’RM’) from dual; IV表示4月   
  104. Month 用9个字符长度表示的月份名 Select to_char(sysdate,’Month’) from dual; May后跟6个空格表示5月   
  105. WW 当年第几周 Select to_char(sysdate,’WW’) from dual; 24表示2002年6月13日为第24周   
  106. W 本月第几周 Select to_char(sysdate,’W’) from dual; 2002年10月1日为第1周   
  107. DDD 当年第几, 1月1日为001,2月1日为032 Select to_char(sysdate,’DDD’) from dual; 363 2002年1 2月2 9日为第363天   
  108. DD 当月第几天 Select to_char(sysdate,’DD’) from dual; 04 10月4日为第4天   
  109. D 周内第几天 Select to_char(sysdate,’D’) from dual; 5 2002年3月14日为星期一   
  110. DY 周内第几天缩写 Select to_char(sysdate,’DY’) from dual; SUN 2002年3月24日为星期天   
  111. HH或HH12 12进制小时数 Select to_char(sysdate,’HH’) from dual; 02 午夜2点过8分为02   
  112. HH24 24小时制 Select to_char(sysdate,’HH24’) from dual; 14 下午2点08分为14   
  113. MI 分钟数(0~59) Select to_char(sysdate,’MI’) from dual; 17下午4点17分   
  114. SS 秒数(0~59) Select to_char(sysdate,’SS’) from dual; 22 11点3分22秒   
  115. 提示注意不要将MM格式用于分钟(分钟应该使用MI)。MM是用于月份的格式,将它用于分钟也能工作,但结果是错误的。   
  116.   
  117.   
  118. 现在给出一些实践后的用法:  
  119.   
  120. 1。上月末天:  
  121. SQL> select to_char(add_months(last_day(sysdate),-1),'yyyy-MM-dd') LastDay from  
  122. dual;  
  123.   
  124. LASTDAY  
  125. ----------  
  126. 2005-05-31  
  127.   
  128. 2。上月今天  
  129. SQL> select to_char(add_months(sysdate,-1),'yyyy-MM-dd') PreToday from dual;  
  130.   
  131.   
  132. PRETODAY  
  133. ----------  
  134. 2005-05-21  
  135.   
  136. 3.上月首天  
  137. SQL> select to_char(add_months(last_day(sysdate)+1,-2),'yyyy-MM-dd') firstDay from dual;  
  138.   
  139. FIRSTDAY  
  140. ----------  
  141. 2005-05-01  
  142.   
  143. 4.按照每周进行统计  
  144. SQL> select to_char(sysdate,'ww'from dual group by to_char(sysdate,'ww');  
  145.   
  146. TO  
  147. --  
  148. 25  
  149.   
  150. 5。按照每月进行统计  
  151. SQL> select to_char(sysdate,'mm'from dual group by to_char(sysdate,'mm');  
  152.   
  153. TO  
  154. --  
  155. 06  
  156.   
  157. 6。按照每季度进行统计  
  158. SQL> select to_char(sysdate,'q'from dual group by to_char(sysdate,'q');  
  159.   
  160. T  
  161. -  
  162. 2  
  163.   
  164. 7。按照每年进行统计  
  165. SQL> select to_char(sysdate,'yyyy'from dual group by to_char(sysdate,'yyyy');  
  166.   
  167. TO_C  
  168. ----  
  169. 2005  
  170.   
  171. 8.要找到某月中所有周五的具体日期   
  172. select to_char(t.d,'YY-MM-DD'from (   
  173. select trunc(sysdate, 'MM')+rownum-1 as d   
  174. from dba_objects   
  175. where rownum < 32) t   
  176. where to_char(t.d, 'MM') = to_char(sysdate, 'MM'--找出当前月份的周五的日期   
  177.   
  178. and trim(to_char(t.d, 'Day')) = '星期五'   
  179. --------   
  180. 03-05-02   
  181. 03-05-09   
  182. 03-05-16   
  183. 03-05-23   
  184. 03-05-30    
  185.   
  186. 如果把where to_char(t.d, 'MM') = to_char(sysdate, 'MM')改成sysdate-90,即为查找当前月份的前三个月中的每周五的日期。  
  187.   
  188. 9.oracle中时间运算  
  189.   
  190. 内容如下:   
  191. 1、oracle支持对日期进行运算   
  192. 2、日期运算时是以天为单位进行的   
  193. 3、当需要以分秒等更小的单位算值时,按时间进制进行转换即可   
  194. 4、进行时间进制转换时注意加括号,否则会出问题   
  195.   
  196. SQL> alter session set nls_date_format='yyyy-mm-dd hh:mi:ss';   
  197.   
  198. 会话已更改。   
  199.   
  200. SQL> set serverout on   
  201. SQL> declare   
  202.    2 DateValue date;   
  203.    3 begin   
  204.    4 select sysdate into DateValue from dual;   
  205.    5 dbms_output.put_line('源时间:'||to_char(DateValue));   
  206.    6 dbms_output.put_line('源时间减1天:'||to_char(DateValue-1));   
  207.    7 dbms_output.put_line('源时间减1天1小时:'||to_char(DateValue-1-1/24));   
  208.    8 dbms_output.put_line('源时间减1天1小时1分:'||to_char(DateValue-1-1/24-1/(24*60)));   
  209.    9 dbms_output.put_line('源时间减1天1小时1分1秒:'||to_char(DateValue-1-1/24-1/(24*60)-1/(24*60*60)));   
  210. 10 end;   
  211. 11 /   
  212. 源时间:2003-12-29 11:53:41   
  213. 源时间减1天:2003-12-28 11:53:41   
  214. 源时间减1天1小时:2003-12-28 10:53:41   
  215. 源时间减1天1小时1分:2003-12-28 10:52:41   
  216. 源时间减1天1小时1分1秒:2003-12-28 10:52:40   
  217.   
  218. PL/SQL 过程已成功完成。  
  219.   
  220.   
  221. 在Oracle中实现时间相加处理  
  222. -- 名称:Add_Times  
  223. -- 功能:返回d1与NewTime相加以后的结果,实现时间的相加  
  224. -- 说明:对于NewTime中的日期不予考虑  
  225. -- 日期:2004-12-07  
  226. -- 版本:1.0  
  227. -- 作者:Kevin  
  228.   
  229.   
  230. create or replace function Add_Times(d1 in date,NewTime in datereturn date   
  231. is  
  232.    hh   number;  
  233.    mm   number;  
  234.    ss   number;  
  235.    hours number;  
  236.    dResult   date;    
  237. begin  
  238.    -- 下面依次取出时、分、秒  
  239.    select to_number(to_char(NewTime,'HH24')) into hh from dual;  
  240.    select to_number(to_char(NewTime,'MI')) into mm from dual;  
  241.    select to_number(to_char(NewTime,'SS')) into ss from dual;  
  242.    -- 换算出NewTime中小时总和,在一天的百分几  
  243.    hours := (hh + (mm / 60) + (ss / 3600))/ 24;  
  244.    -- 得出时间相加后的结果  
  245.    select d1 + hours into dResult from dual;  
  246.    return(dResult);  
  247. end Add_Times;  
  248.   
  249.   
  250. -- 测试用例  
  251. -- select Add_Times(sysdate,to_date('2004-12-06 03:23:00','YYYY-MM-DD HH24:MI:SS')) from dual  
  252.   
  253.   
  254. 在Oracle9i中计算时间差  
  255. 计算时间差是Oracle DATA数据类型的一个常见问题。Oracle支持日期计算,你可以创建诸如“日期1-日期2”这样的表达式来计算这两个日期之间的时间差。   
  256.      
  257.     
  258. 一旦你发现了时间差异,你可以使用简单的技巧来以天、小时、分钟或者秒为单位来计算时间差。为了得到数据差,你必须选择合适的时间度量单位,这样就可以进行数据格式隐藏。   
  259.     
  260. 使用完善复杂的转换函数来转换日期是一个诱惑,但是你会发现这不是最好的解决方法。   
  261.     
  262. round(to_number(end-date-start_date))- 消逝的时间(以天为单位)   
  263.     
  264. round(to_number(end-date-start_date)*24)- 消逝的时间(以小时为单位)   
  265.     
  266. round(to_number(end-date-start_date)*1440)- 消逝的时间(以分钟为单位)   
  267.     
  268. 显示时间差的默认模式是什么?为了找到这个问题的答案,让我们进行一个简单的SQL *Plus查询。   
  269.     
  270. SQL> select sysdate-(sysdate-3) from dual;   
  271.     
  272. SYSDATE-(SYSDATE-3)   
  273. -------------------   
  274.                    3    
  275.     
  276. 这里,我们看到了Oracle使用天来作为消逝时间的单位,所以我们可以很容易的使用转换函数来把它转换成小时或者分钟。然而,当分钟数不是一个整数时,我们就会遇到放置小数点的问题。   
  277.     
  278. Select   
  279.      (sysdate-(sysdate-3.111))*1440   
  280. from   
  281.      dual;   
  282.     
  283. (SYSDATE-(SYSDATE-3.111))*1440   
  284. ------------------------------   
  285.                      4479.83333    
  286.     
  287. 当然,我们可以用ROUND函数(即取整函数)来解决这个问题,但是要记住我们必须首先把DATE数据类型转换成NUMBER数据类型。   
  288.     
  289. Select   
  290.      round(to_number(sysdate-(sysdate-3.111))*1440)   
  291. from   
  292.      dual;   
  293.     
  294. ROUND(TO_NUMBER(SYSDATE-(SYSDATE-3.111))*1440)   
  295. ----------------------------------------------   
  296.                                            4480    
  297.     
  298. 我们可以用这些函数把一个消逝时间近似转换成分钟并把这个值写入Oracle表格中。在这个例子里,我们有一个离线(logoff)系统级触发机制来计算已经开始的会话时间并把它放入一个Oracle STATSPACK USER_LOG扩展表格之中。   
  299.     
  300. Update   
  301.      perfstat.stats$user_log   
  302. set   
  303.      elapsed_minutes =   
  304.      round(to_number(logoff_time-logon_time)*1440)   
  305. where   
  306.      user = user_id   
  307. and   
  308.      elapsed_minutes is NULL;   
  309.   
  310. 查出任一年月所含的工作日  
  311. CREATE OR REPLACE FUNCTION Get_WorkingDays(  
  312.    ny IN VARCHAR2  
  313. RETURN INTEGER IS  
  314. /*------------------------------------------------------------------------------------------  
  315. 函数名称:Get_WorkingDays  
  316. 中文名称:求某一年月中共有多少工作日  
  317. 作者姓名: XINGPING  
  318. 编写时间: 2004-05-22  
  319. 输入参数:NY:所求包含工作日数的年月,格式为yyyymm,如200405  
  320. 返 回 值:整型值,包含的工作日数目。  
  321. 算法描述:  
  322.      1).列举出参数给出的年月中的每一天。这里使用了一个表(ljrq是我的库中的一张表。这个表可以是有权访问的、记录条数至少为31的任意一张表或视图)来构造出某年月的每一天。  
  323.      2).用这些日期和一个已知星期几的日期相减(2001-12-30是星期天),所得的差再对7求模。如果所求年月在2001-12-30以前,那么所得的差既是负数,求模后所得值范围为大于-6,小于0,如-1表示星期六,故先将求模的结果加7,再求7的模.  
  324.      3).过滤掉结果集中值为0和6的元素,然后求count,所得即为工作日数目。        
  325. -------------------------------------------------------------------------------------------------*/  
  326.    Result INTEGER;  
  327. BEGIN  
  328.    SELECT COUNT(*) INTO Result  
  329.      FROM (SELECT MOD(MOD(q.rq-to_date('2001-12-30','yyyy-mm-dd'),7),7) weekday  
  330.              FROM ( SELECT to_date(ny||t.dd,'yyyymmdd') rq  
  331.                      FROM (SELECT substr(100+ROWNUM,2,2) dd   
  332.                              FROM ljrq z WHERE Rownum<=31  
  333.                            ) t  
  334.                      WHERE to_date(ny||t.dd,'yyyymmdd')   
  335.                        BETWEEN to_date(ny,'yyyymm')   
  336.                            AND last_day(to_date(ny,'yyyymm'))  
  337.                  )q  
  338.          ) a     
  339.      WHERE a.weekday NOT IN(0,6);      
  340.    RETURN Result;    
  341. END Get_WorkingDays;  
  342.   
  343. ______________________________________  
  344.   
  345. 还有一个版本  
  346. CREATE OR REPLACE FUNCTION Get_WorkingDays(  
  347.    ny IN VARCHAR2  
  348. RETURN INTEGER IS  
  349. /*-----------------------------------------------------------------------------------------  
  350. 函数名称:Get_WorkingDays  
  351. 中文名称:求某一年月中共有多少工作日  
  352. 作者姓名: XINGPING  
  353. 编写时间: 2004-05-23  
  354. 输入参数:NY:所求包含工作日数的年月,格式为yyyymm,如200405  
  355. 返 回 值:整型值,包含的工作日数目。  
  356. 算法描述:使用Last_day函数计算出参数所给年月共包含多少天,根据这个值来构造一个循环。在这个循环中先求这个月的每一天与一个已知是星期天的日期(2001-12-30是星期天)的差,所得的差再对7求模。如果所求日期在2001-12-30以前,那么所得的差既是负数,求模后所得值范围为大于-6,小于0,如-1表示星期六,故先将求模的结果加7,再求7的模. 如过所得值不等于0和6(即不是星期六和星期天),则算一个工作日。        
  357. ----------------------------------------------------------------------------------------*/  
  358.    Result INTEGER := 0;  
  359.    myts INTEGER;       --所给年月的天数  
  360.    scts INTEGER;       --某天距2001-12-30所差的天数  
  361.    rq   DATE;  
  362.    djt INTEGER := 1;   --   
  363. BEGIN  
  364.    myts := to_char(last_day(to_date(ny,'yyyymm')),'dd');    
  365.    LOOP   
  366.      rq := TO_date(ny||substr(100+djt,2),'yyyymmdd');  
  367.      scts := rq - to_date('2001-12-30','yyyy-mm-dd');  
  368.      IF MOD(MOD(scts,7)+7,7) NOT IN(0,6) THEN  
  369.        Result := Result + 1;  
  370.      END IF;  
  371.      djt := djt + 1;    
  372.      EXIT WHEN djt>myts;  
  373.    END LOOP;    
  374.    RETURN Result;    
  375. END Get_WorkingDays;  
  376.   
  377. 以上两个版本的比较  
  378.   
  379. 第一个版本一条SQL语句就可以得出结果,不需要编程就可以达到目的。但需要使用任意一张有权访问的、记录条数至少为31的一张表或视图。  
  380.      第二个版本需要编程,但不需要表或者视图。  
  381.      这两个版本都还存在需要完善的地方,即没有考虑节日,如五一、十一、元旦、春节这些节假期都没有去除。这些节假日应该维护成一张表,然后通过查表来去除这些节假日  

0 0
原创粉丝点击