当前位置: 代码迷 >> Oracle开发 >> oracle求统计SQL解决方案
  详细解决方案

oracle求统计SQL解决方案

热度:12   发布时间:2016-04-24 07:22:58.0
oracle求统计SQL
类型 日期(yyyymmdd) 操作时间(yyyy-mm-dd hh24:mi:ss) 序列 00-99
type1 20120801 20120801 13:01:01 98
type1 20120801 20120801 13:01:02 99
type1 20120801 20120801 13:02:02 00
type1 20120801 20120801 13:02:03 01

type2 20120801 20120801 13:03:01 99
type2 20120801 20120801 13:03:02 00
type2 20120801 20120801 13:05:01 02

各位高手请指点一下,这样怎么写统计SQL
因为序列为00-99 按操作时间顺序并且“循环”但不会有重复数据。

结实现结果

类型 日期 是否连续 开始序列 结束序列 条数
type1 20120801 是 98 01 4
type2 20120801 否 99 02 3

------解决方案--------------------
SQL code
SQL> create table t(  2  类型 varchar2(5),  3  日期 varchar2(8),  4  操作时间 date,  5  序列 varchar2(2)  6  );表已创建。SQL> insert into t values('type1','20120801',to_date('20120801 13:01:01','yyyymmdd hh24:mi:ss'),'98');已创建 1 行。SQL> insert into t values('type1','20120801',to_date('20120801 13:01:02','yyyymmdd hh24:mi:ss'),'99');已创建 1 行。SQL> insert into t values('type1','20120801',to_date('20120801 13:02:02','yyyymmdd hh24:mi:ss'),'00');已创建 1 行。SQL> insert into t values('type1','20120801',to_date('20120801 13:02:03','yyyymmdd hh24:mi:ss'),'01');已创建 1 行。SQL> insert into t values('type2','20120801',to_date('20120801 13:03:01','yyyymmdd hh24:mi:ss'),'99');已创建 1 行。SQL> insert into t values('type2','20120801',to_date('20120801 13:03:02','yyyymmdd hh24:mi:ss'),'00');已创建 1 行。SQL> insert into t values('type2','20120801',to_date('20120801 13:05:01','yyyymmdd hh24:mi:ss'),'02');已创建 1 行。SQL> commit;提交完成。SQL> select t.类型,t.日期,  2      case when count(t7.类型)>0 then '否' else '是' end 是否连续,  3      min(t3.开始序列) 开始序列,min(t4.结束序列) 结束序列,count(t.类型) 条数  4  from t  5  left join(  6  select t.类型,t.日期,t.序列 开始序列  7  from t,(select 类型,日期,min(操作时间) 最早操作时间 from t  8      group by 类型,日期) t1  9  where t.类型=t1.类型 and t.日期=t1.日期 and t.操作时间=t1.最早操作时间 10  ) t3 on t.类型=t3.类型 and t.日期=t3.日期 11  left join( 12  select t.类型,t.日期,t.序列 结束序列 13  from t,(select 类型,日期,max(操作时间) 最晚操作时间 from t 14      group by 类型,日期) t2 15  where t.类型=t2.类型 and t.日期=t2.日期 and t.操作时间=t2.最晚操作时间 16  ) t4 on t.类型=t4.类型 and t.日期=t4.日期 17  left join ( 18  select t5.类型,t5.日期 from 19  (select row_number() over(partition by 类型,日期 order by 操作时间) 顺序, 20      类型,日期,操作时间,序列 from t) t5, 21  (select row_number() over(partition by 类型,日期 order by 操作时间) 顺序, 22      类型,日期,操作时间,序列 from t) t6 23  where t5.类型=t6.类型 and t5.日期=t5.日期 and t5.顺序=t6.顺序-1 24  and abs(t6.序列-t5.序列) not in(1,99) 25  ) t7 on t.类型=t7.类型 and t.日期=t7.日期 26  group by t.类型,t.日期;类型       日期             是否连 开始 结束       条数                         ---------- ---------------- ------ ---- ---- ----------                         type1      20120801         是     98   01            4                         type2      20120801         否     99   02            3
------解决方案--------------------
SQL code
--单独贴一个sqlSELECT 类型,       日期,       DECODE(MIN( --取最小值 如果取到的是 1:说明序列是连续的,0:说明序列是不连续的                  CASE                  --如果当前的序列-下一条的序列 不在 (0, 1, 99) 中,说明 序列不是连续的                    WHEN ABS(序列 - LEAD_) NOT IN (0, 1, 99) THEN                     0 --不连续用0表示                    ELSE                     1 --连续用1表示                  END),              0,              '否', -- 0:说明序列是不连续的,转换为"否"              '是' -- 1:说明序列是连续的,转换为"是"              ) 是否连续,       START_V 开始序列,       END_V 结束序列,       COUNT(1) 条数  FROM (SELECT 类型,               日期,               操作时间,               序列,               --按照类型和日期分组、操作时间升序排序,取第一条数据即 开始序列               FIRST_VALUE(序列) OVER(PARTITION BY 类型, 日期 ORDER BY 操作时间) START_V,               --按照类型和日期分组、操作时间降序排序,取第一条数据即 结束序列               FIRST_VALUE(序列) OVER(PARTITION BY 类型, 日期 ORDER BY 操作时间 DESC) END_V,               --按照类型和日期分组、操作时间升序排序  取下一条数据的 序列,取不到的取当前条               LEAD(序列, 1, 序列) OVER(PARTITION BY 类型, 日期 ORDER BY 操作时间) LEAD_          FROM T) GROUP BY 类型, 日期, START_V, END_V --因为相同的[类型, 日期]分组[START_V, END_V]也是相同的,想不明白可以单独执行下内层sql
  相关解决方案