Mt表有3列:
user_id, start_time, end_time
我想编写一个SQL查询,它可以以
的形式返回它Time Spent Users
0-30 sec 4
30-60 sec 20
1- 5 min 1
5-30 min 0
30-60 min 0
60+ min 0
类别名称'a - b'包含所有值t,a <= t < b
。
我可以把花时间固定下来。
我的数据:
user_id start_time end_time
230 08-NOV-15 09.13.42.000000000 PM 08-NOV-15 09.13.42.000000000 PM
231 08-NOV-15 11.53.32.000000000 PM 08-NOV-15 11.54.16.000000000 PM
请告知是否可以使用单个Oracle SQL查询
答案 0 :(得分:2)
既然你没有提供任何解决这个谜团的尝试,我只是给你一些步骤,这些步骤可以给你预期的结果。
CASE
语句来实现此目的。GROUP BY
语句,按照步骤2中定义的字符串对结果进行分组。user_id
列与count()
汇总,以获得结果。如果您对上述内容有任何疑问,请随时放弃。
此外,请确保您的时间范围不会重叠,就像您在问题中所做的那样。这会产生奇怪的结果。
答案 1 :(得分:2)
首先,无论条目是否匹配,您都有不同长度的时间范围,并且您希望它们显示出来。因此,第一项任务是:为这些范围创建行。然后外连接表的记录并计算。
要获得时差,您需要从另一个中减去一个日期时间。这给你几天或几小部分。乘以24得到小时,24x60得到分钟或24x60x60得到秒。这仅适用于数据类型DATE,因此,如果您改为使用TIMESTAMP,则必须先将其转换为DATE(或者您必须使用间隔代替)。
select c.category as time_spent, count(user_id) as users
from
(
select '0-30 sec' as category, 0 as min_secs, 30 as max_secs, 1 as sortkey from dual
union all
select '30-60 sec' as category, 30 as min_secs, 60 as max_secs, 2 as sortkey from dual
union all
select '1-5 min' as category, 60 as min_secs, 300 as max_secs, 3 as sortkey from dual
union all
select '5-30 min' as category, 300 as min_secs, 1800 as max_secs, 4 as sortkey from dual
union all
select '30-60 min' as category, 1800 as min_secs,3600 as max_secs, 5 as sortkey from dual
union all
select '60min+' as category, 3600 as min_secs, null as max_secs, 6 as sortkey from dual
) c
left join mytable m
on ((cast(m.end_time as date) - cast(m.start_time as date)) * 24*60*60
>= c.min_secs or c.min_secs is null)
and ((cast(m.end_time as date) - cast(m.start_time as date)) * 24*60*60
<= c.max_secs or c.max_secs is null)
group by c.category
order by min(c.sortkey);
SQL小提琴:http://www.sqlfiddle.com/#!4/a581be/4
正如考虑我已经提到的:你的范围重叠。所以花费30秒的时间当然都属于“0-30秒”和“30-60秒”。这不是问题,甚至可能是期望的,但你应该知道它。