数据库时间段分组查询解决方法和数据转储方法

原文链接: http://www.cnblogs.com/xiaoyz/archive/2008/06/09/1216279.html

问题:将Table1中的数据按照时间段以及其他可能的主键进行统计,然后转存到另一个表Table2中。

说明:时间段分类有两种,一是标准的按照分钟、小时、天等进行分段统计,二是用户自定义时间段,比如上午8点到11点,下午1点到5点。

原理:对时间粒度进行分类,相同的时间段内的时间取一个相同的标示,然后对其分组查询。

方法:对于第一类时间段,可以采用取分钟数,小时数,天数作为标示。
       对于SQL Server,采用datediff(hour,'2007-5-17',Time)函数,可以使用minute,day等不同粒度。例如15分钟可以这样处理datediff(minute,'2007-5-17',myTime)/15,不要忘了反过来恢复时间时应该将该值再乘以15然后与标准时间'2007-5-17'相加 dateadd(minute,stime*15,'2007-5-17')
       对于Oracle,采用时间相减,得到一个小数,单位是天,乘以相关值再取整得到天数、小时数、分钟等,如
trunc((mytime-TO_DATE('2007-5-17 0:00:00','yyyy-mm-dd hh24:mi:ss'))*96)得到的是15分钟的分组标示。
       对于第二类时间段,另建一个表,存储开始时间、结束时间、标示,然后利用该表联合查询。

注意:对于转存表中已经有相关数据可能造成失败的情况进行判别,防止出错。这样执行第二次,就不会再插入相同的数据了。

示例:

第一类解决方法:

 1 /**/ /** SQL Server   **/
 2 CREATE   TABLE   [ dbo ] . [ Table1 ]  (
 3 [ myTime ]   [ datetime ]   NOT   NULL  ,
 4 [ ac ]   [ char ]  ( 10 NOT   NULL  ,
 5 [ bi ]   [ int ]   NOT   NULL  ,
 6 [ ci ]   [ int ]   NOT   NULL  
 7 )
 8 GO
 9
10 CREATE   TABLE   [ dbo ] . [ Table2 ]  (
11 [ myTime ]   [ datetime ]   NOT   NULL  ,
12 [ ac ]   [ char ]  ( 10 NOT   NULL  ,
13 [ bi ]   [ int ]   NOT   NULL  ,
14 [ ci ]   [ int ]   NOT   NULL  
15 )
16 GO
17
18 delete   from  Table1;
19 delete   from  Table2;
20
21 insert   into  Table1  values ( ' 2007-5-17 1:00:00 ' , ' Tom ' , 25 , 300 );
22 insert   into  Table1  values ( ' 2007-5-17 1:15:00 ' , ' Tom ' , 25 , 400 );
23 insert   into  Table1  values ( ' 2007-5-17 1:30:00 ' , ' Tom ' , 25 , 500 );
24 insert   into  Table1  values ( ' 2007-5-17 2:00:00 ' , ' Tom ' , 25 , 600 );
25 insert   into  Table1  values ( ' 2007-5-17 2:30:00 ' , ' Tom ' , 25 , 550 );
26 insert   into  Table1  values ( ' 2007-5-17 3:00:00 ' , ' Tom ' , 25 , 560 );
27 insert   into  Table1  values ( ' 2007-5-17 4:15:00 ' , ' Tom ' , 25 , 800 );
28 insert   into  Table1  values ( ' 2007-5-17 3:30:00 ' , ' Jerry ' , 20 , 200 );
29 insert   into  Table1  values ( ' 2007-5-17 4:00:00 ' , ' Jerry ' , 20 , 300 );
30 insert   into  Table1  values ( ' 2007-5-17 4:15:00 ' , ' Jerry ' , 20 , 500 );
31 insert   into  Table1  values ( ' 2007-5-17 2:30:00 ' , ' Jerry ' , 20 , 150 );
32 GO
33
34 insert   into  Table2 
35 select   dateadd (hour,stime, ' 2007-5-17 ' ) newtime,ac,bi,cisum  from         -- 两个select,因为里面的一个是聚合查询,外面一个要将时间转化回来,不要企图合并
36     (    select   datediff (hour, ' 2007-5-17 ' ,myTime) stime,ac,bi, sum (ci) cisum 
37             from  Table1 
38             where  ( not   exists                                             -- 对插入数据进行保护,如果仅仅查询,这部分就不需要
39                      (  select   *   from  Table2 
40                            where  myTime >= ' 2007-5-17 '  
41                            and  myTime < ' 2007-5-18 '
42                       )
43     )
44             and  (myTime >= ' 2007-5-17 '   and  myTime  < ' 2007-5-18 ' )             -- 统计转存某一时段的数据
45            group   by   datediff (hour, ' 2007-5-17 ' ,myTime),ac,bi              -- 分组方法
46      ) tablea 
47 order   by  newtime
48
49

 1 /**/ /** ORACLE **/
 2
 3 CREATE   TABLE  Table1 (
 4 myTime DATE  NOT   NULL  ,
 5 ac  varchar2 ( 10 NOT   NULL  ,
 6 bi  int   NOT   NULL  ,
 7 ci  int   NOT   NULL  
 8 );
 9
10 CREATE   TABLE  Table2 (
11 myTime DATE  NOT   NULL  ,
12 ac  varchar2 ( 10 NOT   NULL  ,
13 bi  int   NOT   NULL  ,
14 ci  int   NOT   NULL  
15 );
16
17 delete   from  Table1;
18 delete   from  Table2;
19
20 insert   into  Table1  values (TO_DATE( ' 2007-5-17 1:00:00 ' , ' yyyy-mm-dd hh24:mi:ss ' ), ' Tom ' , 25 , 300 );
21 insert   into  Table1  values (TO_DATE( ' 2007-5-17 1:15:00 ' , ' yyyy-mm-dd hh24:mi:ss ' ), ' Tom ' , 25 , 400 );
22 insert   into  Table1  values (TO_DATE( ' 2007-5-17 1:30:00 ' , ' yyyy-mm-dd hh24:mi:ss ' ), ' Tom ' , 25 , 500 );
23 insert   into  Table1  values (TO_DATE( ' 2007-5-17 2:00:00 ' , ' yyyy-mm-dd hh24:mi:ss ' ), ' Tom ' , 25 , 600 );
24 insert   into  Table1  values (TO_DATE( ' 2007-5-17 2:30:00 ' , ' yyyy-mm-dd hh24:mi:ss ' ), ' Tom ' , 25 , 550 );
25 insert   into  Table1  values (TO_DATE( ' 2007-5-17 3:00:00 ' , ' yyyy-mm-dd hh24:mi:ss ' ), ' Tom ' , 25 , 560 );
26 insert   into  Table1  values (TO_DATE( ' 2007-5-17 4:15:00 ' , ' yyyy-mm-dd hh24:mi:ss ' ), ' Tom ' , 25 , 800 );
27 insert   into  Table1  values (TO_DATE( ' 2007-5-17 3:30:00 ' , ' yyyy-mm-dd hh24:mi:ss ' ), ' Jerry ' , 20 , 200 );
28 insert   into  Table1  values (TO_DATE( ' 2007-5-17 4:00:00 ' , ' yyyy-mm-dd hh24:mi:ss ' ), ' Jerry ' , 20 , 300 );
29 insert   into  Table1  values (TO_DATE( ' 2007-5-17 4:15:00 ' , ' yyyy-mm-dd hh24:mi:ss ' ), ' Jerry ' , 20 , 500 );
30 insert   into  Table1  values (TO_DATE( ' 2007-5-17 2:30:00 ' , ' yyyy-mm-dd hh24:mi:ss ' ), ' Jerry ' , 20 , 150 );
31 commit ;
32
33 insert   into  Table2
34 select  TO_DATE( ' 2007-5-17 0:00:00 ' , ' yyyy-mm-dd hh24:mi:ss ' ) + stime / 24  newtime,ac,bi,cisum  from
35     (    select  trunc((mytime - TO_DATE( ' 2007-5-17 0:00:00 ' , ' yyyy-mm-dd hh24:mi:ss ' )) * 24 ) stime,ac,bi, sum (ci) cisum 
36         from  Table1 
37         where  ( not   exists
38                   ( select   *   from  Table2 
39                         where  mytime >= TO_DATE( ' 2007-5-17 0:00:00 ' , ' yyyy-mm-dd hh24:mi:ss '
40                         and  mytime < TO_DATE( ' 2007-5-18 0:00:00 ' , ' yyyy-mm-dd hh24:mi:ss ' )
41                   )
42        ) 
43         and  ( mytime >= TO_DATE( ' 2007-5-17 0:00:00 ' , ' yyyy-mm-dd hh24:mi:ss '
44               and  mytime < TO_DATE( ' 2007-5-18 0:00:00 ' , ' yyyy-mm-dd hh24:mi:ss ' ))
45         group   by  trunc((mytime - TO_DATE( ' 2007-5-17 0:00:00 ' , ' yyyy-mm-dd hh24:mi:ss ' )) * 24 ),ac,bi) tablea 
46 order   by  newtime;
47
48

第二类解决方法

不具体写了,因为要比上面的简单,这里就非常简单的表示一下查询原理,SQL Server

 1 CREATE   TABLE   [ dbo ] . [ Table3 ]  (
 2 [ starttime ]   [ datetime ]   NULL  ,
 3 [ endtime ]   [ datetime ]   NULL  ,
 4 [ id ]   [ int ]   NULL      -- 看你怎么用了,没有这个也可以
 5 )
 6 GO
 7
 8 delete   from  Table3;
 9
10 insert   into  Table3  values ( ' 2007-5-17 0:0:0 ' , ' 2007-5-17 2:0:0 ' , 1 );
11 insert   into  Table3  values ( ' 2007-5-17 3:0:0 ' , ' 2007-5-17 5:0:0 ' , 2 );
12 GO
13
14 select  id,ac,bi, sum (ci) cisum 
15             from  Table1,Table3  where  ( myTime >= starttime  and  myTime < endTime)
16            group   by  id,ac,bi  order   by  id
17

转载于:https://www.cnblogs.com/xiaoyz/archive/2008/06/09/1216279.html

猜你喜欢

转载自blog.csdn.net/weixin_30511107/article/details/94801713
今日推荐