Oracle日期段数据统计

oracle 日期函数介绍:
在oracle中有很多关于日期的函数,如:
1、add_months()用于从一个日期值增加或减少一些月份
date_value:=add_months(date_value,number_of_months)
例:
SQL> select add_months(sysdate,12) "Next Year" from dual;
 
Next Year
----------
13-11月-04
 
SQL> select add_months(sysdate,112) "Last Year" from dual;
 
Last Year
----------
13-3月 -13
 
SQL> 
 
2、current_date()返回当前会放时区中的当前日期
date_value:=current_date
SQL> column sessiontimezone for a15
SQL> select sessiontimezone,current_date from dual;
 
SESSIONTIMEZONE CURRENT_DA
--------------- ----------
+08:00          13-11月-03
 
SQL> alter session set time_zone='-11:00'
   2  /
 
会话已更改。
 
SQL> select sessiontimezone,current_timestamp from dual;
 
SESSIONTIMEZONE CURRENT_TIMESTAMP
--------------- ------------------------------------
-11:00          12-11月-03 04.59.13.668000 下午 -11:
                 00
 
SQL> 
 
3、current_timestamp()以timestamp with time zone数据类型返回当前会放时区中的当前日期
timestamp_with_time_zone_value:=current_timestamp([timestamp_precision])
SQL> column sessiontimezone for a15
SQL> column current_timestamp format a36
SQL> select sessiontimezone,current_timestamp from dual;
 
SESSIONTIMEZONE CURRENT_TIMESTAMP
--------------- ------------------------------------
+08:00          13-11月-03 11.56.28.160000 上午 +08:
                 00
 
SQL> alter session set time_zone='-11:00'
   2  /
 
会话已更改。
 
SQL> select sessiontimezone,current_timestamp from dual;
 
SESSIONTIMEZONE CURRENT_TIMESTAMP
--------------- ------------------------------------
-11:00          12-11月-03 04.58.00.243000 下午 -11:
                 00
 
SQL> 
 
4、dbtimezone()返回时区
varchar_value:=dbtimezone
SQL> select dbtimezone from dual;
 
DBTIME
------
-07:00
 
SQL> 
 
5、extract()找出日期或间隔值的字段值
date_value:=extract(date_field from [datetime_value|interval_value])
SQL> select extract(month from sysdate) "This Month" from dual;
 
This Month
----------
         11
 
SQL> select extract(year from add_months(sysdate,36)) "3 Years Out" from dual;
 
3 Years Out
-----------
        2006
 
SQL> 
 
6、last_day()返回包含了日期参数的月份的最后一天的日期
date_value:=last_day(date_value)
SQL> select last_day(date'2000-02-01') "Leap Yr?" from dual;
 
Leap Yr?
----------
29-2月 -00
 
SQL> select last_day(sysdate) "Last day of this month" from dual;
 
Last day o
----------
30-11月-03
 
SQL> 
 
7、localtimestamp()返回会话中的日期和时间
timestamp_value:=localtimestamp
SQL> column localtimestamp format a28
SQL> select localtimestamp from dual;
 
LOCALTIMESTAMP
----------------------------
13-11月-03 12.09.15.433000
下午
 
SQL> select localtimestamp,current_timestamp from dual;
 
LOCALTIMESTAMP               CURRENT_TIMESTAMP
---------------------------- ------------------------------------
13-11月-03 12.09.31.006000   13-11月-03 12.09.31.006000 下午 +08:
下午                         00


根据日期计算第几周:

//计算第几周
public int GetWeekOfCurrDate(DateTime dt)
        {
            int Week = 1;
            int nYear = dt.Year;
            System.DateTime FirstDayInYear = new DateTime(nYear, 1, 1);
            System.DateTime LastDayInYear = new DateTime(nYear, 12, 31);
            int DaysOfYear = Convert.ToInt32(LastDayInYear.DayOfYear);
            int WeekNow = Convert.ToInt32(FirstDayInYear.DayOfWeek) - 1;
            if (WeekNow < 0) WeekNow = 6;
            int DayAdd = 6 - WeekNow;
            System.DateTime BeginDayOfWeek = new DateTime(nYear, 1, 1);
            System.DateTime EndDayOfWeek = BeginDayOfWeek.AddDays(DayAdd);
            Week = 2;
            for (int i = DayAdd + 1; i <= DaysOfYear; i++)
            {
                BeginDayOfWeek = FirstDayInYear.AddDays(i);
                if (i + 6 > DaysOfYear)
                {
                    EndDayOfWeek = BeginDayOfWeek.AddDays(DaysOfYear - i - 1);
                }
                else
                {
                    EndDayOfWeek = BeginDayOfWeek.AddDays(6);
                }

                if (dt.Month == EndDayOfWeek.Month && dt.Day <= EndDayOfWeek.Day)
                {
                    break;
                }
                Week++;
                i = i + 6;
            }
            return Week;
        }

 

//本周是本年第几周
private int DatePart(System.DateTime dt)
{
   int weeknow = Convert.ToInt32(dt.DayOfWeek);//今天星期几
   int daydiff = (-1) * (weeknow+1);//今日与上周末的天数差
   int days = System.DateTime.Now.AddDays(daydiff).DayOfYear;//上周末是本年第几天
   int weeks = days/7;
   if(days%7 != 0)
{
    weeks++;
   }
   //此时,weeks为上周是本年的第几周
   return (weeks+1);
  }
//本周起止日期
 private string WeekRange(System.DateTime dt)
{
   int weeknow = Convert.ToInt32(dt.DayOfWeek);
   int daydiff = (-1) * weeknow;
   int dayadd = 6-weeknow;
   string dateBegin = System.DateTime.Now.AddDays(daydiff).Date.ToString("MM月dd日");
   string dateEnd = System.DateTime.Now.AddDays(dayadd).Date.ToString("MM月dd日");
   return dateBegin + " - " +dateEnd;
  }

 

获取某年指定周的开始日期和结束日期的通用方法:

获取某年指定周的开始日期和结束日期的通用方法
/**//// <summary>
/// 获取一年中指定的一周的开始日期和结束日期。开始日期遵循ISO 8601即星期一。
/// </summary>
/// <remarks>Write by vrhero</remarks>
/// <param name="year">年(1 到 9999)</param>
/// <param name="weeks">周(1 到 53)</param>
/// <param name="weekrule">确定首周的规则</param>
/// <param name="first">当此方法返回时,则包含参数 year 和 weeks 指定的周的开始日期的 System.DateTime 值;如果失败,则为 System.DateTime.MinValue。如果参数 year 或 weeks 超出有效范围,则操作失败。该参数未经初始化即被传递。</param>
/// <param name="last">当此方法返回时,则包含参数 year 和 weeks 指定的周的结束日期的 System.DateTime 值;如果失败,则为 System.DateTime.MinValue。如果参数 year 或 weeks 超出有效范围,则操作失败。该参数未经初始化即被传递。</param>
/// <returns>成功返回 true,否则为 false。</returns>
public static bool GetDaysOfWeeks(int year, int weeks, CalendarWeekRule weekrule, out DateTime first, out DateTime last)
{
    //初始化 out 参数
    first = DateTime.MinValue;
    last = DateTime.MinValue;

    //不用解释了吧
    if (year < 1 | year > 9999)
        return false;

    //一年最多53周地球人都知道
    if (weeks < 1 | weeks > 53)
        return false;

    //取当年首日为基准为什么?容易得呗
    DateTime firstCurr = new DateTime(year, 1, 1);
    //取下一年首日用于计算
    DateTime firstNext = new DateTime(year + 1, 1, 1);

    //将当年首日星期几转换为数字星期日特别处理ISO 8601 标准
    int dayOfWeekFirst = (int)firstCurr.DayOfWeek;
    if (dayOfWeekFirst == 0) dayOfWeekFirst = 7;

    //得到未经验证的周首日
    first = firstCurr.AddDays((weeks - 1) * 7 - dayOfWeekFirst + 1);

    //周首日是上一年日期的情况
    if (first.Year < year)
    {
        switch (weekrule)
        {
            case CalendarWeekRule.FirstDay:
                //不用解释了吧
                first = firstCurr;
                break;
            case CalendarWeekRule.FirstFullWeek:
                //顺延一周
                first = first.AddDays(7);
                break;
            case CalendarWeekRule.FirstFourDayWeek:
                //周首日距年首日不足4天则顺延一周
                if (firstCurr.Subtract(first).Days > 3)
                {
                    first = first.AddDays(7);
                }
                break;
            default:
                break;
        }
    }

    //得到未经验证的周末日
    last = first.AddDays(7).AddSeconds(-1);

    //周末日是下一年日期的情况
    if (last.Year > year)
    {
        switch (weekrule)
        {
            case CalendarWeekRule.FirstDay:
                last = firstNext.AddSeconds(-1);
                break;
            case CalendarWeekRule.FirstFullWeek:
                //不用处理
                break;
            case CalendarWeekRule.FirstFourDayWeek:
                //周末日距下一年首日不足4天则提前一周
                if (firstNext.Subtract(first).Days < 4)
                {
                    first = first.AddDays(-7);
                    last = last.AddDays(-7);
                }
                break;
            default:
                break;
        }
    }
    return true;
}

 

关于按周统计数据:

关于按周统计数据(Oracle)
方法1:使用to_char函数

select sum(sal) ,
to_char(HIREDATE,'yyyy')||':'||to_char(HIREDATE,'IW') week_sn
from scott.emp
group by to_char(HIREDATE,'yyyy')||':'||to_char(HIREDATE,'IW');

格式'IW'返回当前日期是当年的第几周


方法2:使用next_day()函数

select sum(sal) ,
NEXT_DAY(trunc(HIREDATE),'星期一')-7 weekstart,
NEXT_DAY(trunc(HIREDATE),'星期一') weekend
from scott.emp
group by NEXT_DAY(trunc(HIREDATE),'星期一');

上面这个例子是在中文字符集下使用,如果在英文字符集下则使用:

select sum(sal) ,
NEXT_DAY(trunc(HIREDATE),'Monday')-7 weekstart,
NEXT_DAY(trunc(HIREDATE),'Monday') weekend
from scott.emp
group by NEXT_DAY(trunc(HIREDATE),'Monday');

两种方法比较,第二种方法能够方便的给出周开始和周结束日期,更方便些。

 

临时表:

需要创建一个临时表,请举例说明,谢谢!      
  ---------------------------------------------------------------      
     
  是TEMPORARY      
  CREATE     GLOBAL     TEMPORARY     TABLE     flight_schedule     (      
            startdate     DATE,          
            enddate     DATE,          
            cost     NUMBER)      
     
  ---------------------------------------------------------------      
     
  create     proecdure     name_pro      
  as      
  str     varchar2(100);      
  begin      
  str:='CREATE     GLOBAL     TEMPORARY     TABLE     TABLENAME     ON     COMMIT     PRESERVE     ROWS     as     select     *     from     others_table';      
  execute     immediate     str;      
  end;      
  /  
   
   
   
  可以把临时表指定为事务相关(默认)或者是会话相关:  
  ON   COMMIT   DELETE   ROWS:指定临时表是事务相关的,Oracle在每次提交后截断表。  
  ON   COMMIT   PRESERVE   ROWS:指定临时表是会话相关的,Oracle在会话中止后截断表。  
   
  =================  
  可以创建以下两种临时表:  
  1。会话特有的临时表  
        CREATE   GLOBAL   TEMPORARY   <TABLE_NAME>   (<column   specification>)  
        ON   COMMIT   PRESERVE   ROWS;  
  ========  
  对全局临时表的总结  
   
  在临时表上的操作比在一般的表上的操作要快。因为:  
  1创建临时表不需要往编目表中插入条目,临时表的使用也不需要访问编目表,因此也没有对编目表的争用。  
  2仅有创建临时表的app才可存取临时表,所以在处理临时表时没有锁。  
  3如果指定NOT   LOGGED选项,在处理临时表时不记日志。所以如果有仅在数据库的一个会话中使用的大量临时数据,把这些数据存入临时表能大大提高性能。  
  DECLARE   GLOBAL   TEMPORARY   TABLE   TT(C1   INT,   C2   CHAR(20));  
  在CONNECT   RESET命令后,临时表不再存在。  
  建临时表是动态编译的,所以对临时表的使用也必须放在DECLARE   CURSER   后面  
  CREATE   PROCEDURE   INSTT2(P1   INT,   P2   CHAR(20))  
  BEGIN  
      DECLARE   GLOBAL   TEMPORARY   TABLE   TT(C1   INT,   C2   CHAR(20))   %  
      INSERT   INTO   SESSION.TT   VALUES(P1,   P2);  
      BEGIN  
          DECLARE   C1   CURSOR   WITH   RETURN   FOR   SELECT   *   FROM   SESSION.TT;  
      END;  
  END   %  
   
  2。事务特有的临时表  
        CREATE   GLOBAL   TEMPORARY   <TABLE_NAME>   (<column   specification>)  
        ON   COMMIT   DELETE   ROWS;  
       
      在Oracle中,全局临时表并不会删除,实际上你只需要建立一次,以后直接应用就行了,这与MS和Sybase不一样。实际上在断开数据库连接时,临时表中数据自动清空,不同的Session之间是隔离的,不许要当心相互影响,不过如果起用了连接共享的话,你要用On   Commit   delete   rows使数据仅在事物内部有效。

3建立临时表  
        临时表的定义对所有会话SESSION都是可见的,但是表中的数据只对当前的会话或者事务有效.    
        建立方法:  
  1)   ON   COMMIT   DELETE   ROWS   定义了建立事务级临时表的方法.  
  CREATE   GLOBAL   TEMPORARY   TABLE   admin_work_area  
                  (startdate   DATE,  
                    enddate   DATE,  
                    class   CHAR(20))  
              ON   COMMIT   DELETE   ROWS;  
  EXAMPLE:  
  SQL>   CREATE   GLOBAL   TEMPORARY   TABLE   admin_work_area  
      2                     (startdate   DATE,  
      3                       enddate   DATE,  
      4                       class   CHAR(20))  
      5                 ON   COMMIT   DELETE   ROWS;  
  SQL>   create   table   permernate(   a   number);  
  SQL>   insert   into   admin_work_area   values(sysdate,sysdate,'temperary   table');  
  SQL>   insert   into   permernate   values(1);  
  SQL>   commit;  
  SQL>   select   *   from   admin_work_area;  
  SQL>   select     *   from   permernate;  
    A  
  1  
  2)ON   COMMIT   PRESERVE   ROWS   定义了创建会话级临时表的方法.  
  CREATE   GLOBAL   TEMPORARY   TABLE   admin_work_area  
                  (startdate   DATE,  
                    enddate   DATE,  
                    class   CHAR(20))  
            ON   COMMIT   PRESERVE   ROWS;  
  EXAMPLE:  
   
  会话1:  
  SQL>   drop   table   admin_work_area;  
  SQL>   CREATE   GLOBAL   TEMPORARY   TABLE   admin_work_area  
      2                     (startdate   DATE,  
      3                       enddate   DATE,  
      4                       class   CHAR(20))  
      5               ON   COMMIT   PRESERVE   ROWS;  
  SQL>   insert   into   permernate   values(2);  
  SQL>   insert   into   admin_work_area   values(sysdate,sysdate,'session   temperary');  
  SQL>   commit;  
  SQL>   select   *   from   permernate;  
   
                    A  
  ----------  
                    1  
                    2  
   
  SQL>   select   *   from   admin_work_area;  
   
  STARTDATE     ENDDATE         CLASS  
  ----------   ----------   --------------------  
  17-1&Ocirc;&Acirc;   -03   17-1&Ocirc;&Acirc;   -03   session   temperary  
   
  会话2:  
   
  SQL>   select   *   from   permernate;  
   
                    A  
  ----------  
                    1  
                    2  
   
  SQL>   select   *   from   admin_work_area;  
   
    未选择行.  
   
  会话2看不见会话1中临时表的数据. 

 

根据上面的信息实现存储过程:

CREATE OR REPLACE PACKAGE BODY TodayALL_zjz IS

  --第一层主页统计信息--数据
  PROCEDURE GetIndexTj(Index_OUT OUT MYCURSOR) AS
  BEGIN
    --单维数组
    DECLARE
      --
      fa integer;
      --
      pa integer;
      --
      zhtf integer;
      --
      djclry integer;
      --
      kywp integer;
      --
      blzz integer;
      --
      lgzs integer;
   
      -- mydate  date;
      strdate  varchar(8);
      strdate1 varchar(12);
      strdate2 varchar(12);
   
    begin
      strdate  := TO_CHAR(SYSDATE, 'YYYYMMDD');
      strdate1 := TO_CHAR(SYSDATE, 'YYYYMMDD') + '0000';
      strdate2 := TO_CHAR(SYSDATE + 1, 'YYYYMMDD') + '0000';
   
      --结果1
      SELECT count(*) into blzz FROM ZZRK.JB_TAB WHERE FZRQ = strdate;

      --结果2
      SELECT count(*)
        into lgzs
        FROM lgy.lgy_gnlkjbxx
       WHERE RZSJ >= strdate1
         and RZSJ < strdate2;
   
      OPEN Index_OUT FOR
        SELECT blzz,lgzs
    END;
  END;
end;

 

调用存储过程:

    /// <summary>
    /// 得到统计数据集
    /// </summary>
    /// <param name="cmdText"></param>
    /// <param name="Stime"></param>
    /// <param name="Etime"></param>
    /// <param name="Type"></param>
    private DataSet GetTjData(string cmdText, string Stime, string Etime, string Type)
    {
        DataSet ds = new DataSet();
        OracleConnection Con = new System.Data.OracleClient.OracleConnection(AppConfig.ZHCX);
        Con.Open();
        OracleCommand cmd = new OracleCommand(cmdText, Con);
        cmd.CommandType = CommandType.StoredProcedure;
        OracleParameter[] parm ={
            new OracleParameter("Stime", OracleType.DateTime),
            new OracleParameter("Etime", OracleType.DateTime),
            new OracleParameter("Type", OracleType.Int16),
            new OracleParameter("cur_OUT", OracleType.Cursor) };
        parm[0].Value = DateTime.Parse(Stime);
        parm[1].Value = DateTime.Parse(Etime).AddDays(1);
        parm[2].Value = int.Parse(Type);
        parm[3].Direction = ParameterDirection.Output;

        foreach (OracleParameter op in parm)
        {
            cmd.Parameters.Add(op);
        }
        OracleDataAdapter oda = new OracleDataAdapter(cmd);
        oda.Fill(ds);
        Con.Close();
        return ds;
    }

你可能感兴趣的:(oracle)