我正在尝试创建一个查询来为我的网站生成统计数据,并且我试图弄清楚如何以半小时的间隔制作查询。
根据我偶然发现的另一个问题,我想出了这个:
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 :(得分: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