需求:統計當天的訪問量,每五分鍾采集一次
表結構中有日期字段,類型TIMESTAMP
如果,統計是采用每秒/分鍾/小時/天/周/月/年,都非常容易實現,只要to_char日期字段然后group by分組即可
但是:如果是X秒/分鍾/小時/天/周/月/年 and X>1,就需要變通實現,方法如下:
方案一:臨時表/臨時存儲
統計每5分鍾的訪問量,存入臨時表或者臨時存儲(比如excel)
循環當天整個時間段
然后對臨時表/臨時存儲的數據做排序
方案二:偽列的SQL查詢(數據量小於<1億數據量,且時間列做索引)
分析:5分鍾一次,那就對每條記錄做個偽列,每5分鍾的數據都是一個標識。
比如:創建時間=201604061200 -至- 201604061204,這五分鍾統一標識為201604061200
創建時間=201604061205 -至- 201604061209,這五分鍾統一標識為201604061205
實現起來非常方便:
a. 取出創建時間的分鍾參數:to_char(t.create_time,'mi'),都是兩位:比如01分,07分,13分,19分....
只判斷第二位,如果第二位<5,統一讓分鍾的第二位=0,否則(第二位>=5)統一讓分鍾的第二位=5
而分鍾的第一位不變
比如01分、04分統一標識為00分,05、06、09分統一標識為05分
切割字符串使用substr函數
判斷使用case when
拼接使用||
b.取出創建時間的年月日小時參數,拼裝上第一步的特殊分鍾參數
一個偽列就這么誕生了
關鍵SQL如下:
case when substr(to_char(t.create_time,'mi'),2,1)<5 then to_char(t.create_time,'yyyymmddhh24')||substr(to_char(t.create_time,'mi'),1,1)||0 else to_char(t.create_time,'yyyymmddhh24')||substr(to_char(t.create_time,'mi'),1,1)||5 end as newTime
上一個完整的sql
select count(tmp.id) totalNum,tmp.newTime from( select t.id,t.latest_status, -- ID,狀態 to_char(t.create_time,'yyyymmddhh24mi') oldTime, -- 原來的時間 case when substr(to_char(t.create_time,'mi'),2,1)<5 then to_char(t.create_time,'yyyymmddhh24')||substr(to_char(t.create_time,'mi'),1,1)||0 else to_char(t.create_time,'yyyymmddhh24')||substr(to_char(t.create_time,'mi'),1,1)||5 end as newTime -- 時間段偽列 from acquire_order t where t.create_time>=to_date('20160406000000','yyyymmddhh24miss') order by t.create_time asc ) tmp group by tmp.newTime order by totalNum desc