2012-07-11 70 views
1

我想創建一個查詢來爲我的網站生成統計數據,並且我試圖弄清楚如何製作一個半小時間隔的查詢。Oracle格式化日期間隔

基於另一個問題,我偶然發現,我想出了這一點:

SELECT count(*), dt FROM (
    (SELECT TO_CHAR(TRACK_DATETIME,'dd/mm/yyyy hh24') || ':' || DECODE(TRUNC(to_number(to_char(TRACK_DATETIME,'mi'))/30),0,'00','30') as DT FROM tbl_stat) 
) 
group by dt 

這個偉大的工程,唯一的例外是沒有活動的時間間隔不顯示在所有。有沒有一種方法來顯示所有的半小時一班(即使是空的?)

感謝

+0

可能重複[分組記錄小時按小時或天白天和填補空白爲零或爲空(HTTP ://stackoverflow.com/questions/10798905/grouping-records-hour-by-hour-or-day-by-day-and-filling-gaps-with-zero-or-null) – 2012-07-11 19:34:19

回答

0

這裏的關鍵是產生所有間隔的列表,然後做一個外連接表怎麼看你在每個區間有很多記錄。

假設你有用於查詢的範圍(這我在這裏與varchar2綁定變量的設置,這樣我可以在SQL * Plus輕鬆運行這個,你會從你的Web客戶端做其他的事情,比如?爲JDBC ),你可以這樣做:

var start_time varchar2(16); 
var end_time varchar2(16); 

exec :start_time := '12/07/2012 08:00:00'; 
exec :end_time := '12/07/2012 12:00:00'; 

select start_time + (level - 1)/48 as period_start, 
    start_time + level/48 - interval '1' second as period_end 
from (
    select to_date(:start_time, 'DD/MM/YYYY HH24:MI:SS') start_time, 
     to_date(:end_time, 'DD/MM/YYYY HH24:MI:SS') end_time 
    from dual 
) 
connect by start_time + (level - 1)/48 < end_time; 

生成所有的半小時時間的08:00至12:00之間以列表:

PERIOD_START  PERIOD_END 
------------------- ------------------- 
12/07/2012 08:00:00 12/07/2012 08:29:59 
12/07/2012 08:30:00 12/07/2012 08:59:59 
12/07/2012 09:00:00 12/07/2012 09:29:59 
12/07/2012 09:30:00 12/07/2012 09:59:59 
12/07/2012 10:00:00 12/07/2012 10:29:59 
12/07/2012 10:30:00 12/07/2012 10:59:59 
12/07/2012 11:00:00 12/07/2012 11:29:59 
12/07/2012 11:30:00 12/07/2012 11:59:59 

然後你可以使用它作爲一個CTE或子查詢並在您的實際表中找到匹配記錄:

with tmp_tab as (
    select start_time + (level - 1)/48 as period_start, 
     start_time + level/48 - interval '1' second as period_end 
    from (
     select to_date(:start_time, 'DD/MM/YYYY HH24:MI:SS') start_time, 
      to_date(:end_time, 'DD/MM/YYYY HH24:MI:SS') end_time 
     from dual 
    ) 
    connect by start_time + (level - 1)/48 < end_time 
) 
select to_char(tt.period_start, 'DD/MM/YYYY HH24:MI') dt, 
    count(ts.track_datetime) 
from tmp_tab tt 
left join tbl_stat ts 
on ts.track_datetime between tt.period_start and tt.period_end 
group by tt.period_start 
order by tt.period_start; 

用在只有少數記錄的虛擬表,這給:

DT    COUNT(TS.TRACK_DATETIME) 
---------------- ------------------------ 
12/07/2012 08:00      0 
12/07/2012 08:30      0 
12/07/2012 09:00      1 
12/07/2012 09:30      2 
12/07/2012 10:00      0 
12/07/2012 10:30      1 
12/07/2012 11:00      0 
12/07/2012 11:30      0