我有一个日期和时间的SQL数据库,但它们被合并为一个值(称为时间)。我想确定每小时的条目数,但我无法弄清楚如何做到这一点。 如果我这样做:
Select time from time_table
我得到的结果是:
2016-05-13 07:23:23
2016-05-13 07:34:34
2016-05-14 07:21:00
2016-05-14 09:42:43
我想要的是:
07:23:23
07:34:34
07:21:00
09:42:43
我可以解决这个问题:
07:21:00
07:23:23
07:34:34
09:42:43
或者,最终,我想得到好处:
07-08: 3
08-09: 0
09-10: 1
有没有办法做到这一点?
答案 0 :(得分:1)
通过减去该值的截断,可以从DATE数据类型的值中提取时间:
select time - trunc(time) from.....
这将返回一个小数,> = 0和< 1,代表一天的一小部分。要将其转换为小时:乘以24。
例如,现在是我现在的时间是晚上8:08。然后:
select 24 * (sysdate - trunc(sysdate)) as result from dual;
RESULT
----------
20.1566667
现在,如果我想知道时间,我可以再次trunc()
。我早些时候截断了一个日期;现在结果是一个数字,我截断了一个数字。
全部放在一起(第一部分生成从0到23的整数):
with h ( hr ) as (select level - 1 from dual connect by level <= 24)
select h.hr, count(tt.time) as ct
from h left outer join time_table tt on h.hr = trunc(24 * (tt.time - trunc(tt.time)))
group by h.hr
order by hr -- optional
;
您可以格式化&#34;小时&#34;专栏不同,虽然我不明白这一点;我的解决方案将显示8显示08-09的位置。两者都有相同的信息。
答案 1 :(得分:1)
这是一个包含两个子查询的解决方案,一个用于生成完整的小时列表,另一个用于生成目标表中的数字列表。必须使用外连接才能在没有匹配的情况下产生零小时计数。
请注意,诸如7-8,8-9之类的桶标签意味着重复计算,所以我忽略了支持单个小时。
SQL> select * from t42
2 /
ID TCOL
---------- -------------------
1 2016-05-13 07:23:23
2 2016-05-13 07:34:34
3 2016-05-14 07:21:00
4 2016-05-14 09:42:43
SQL> with hrs as (select level-1 as hr
2 from dual
3 connect by level <= 24 )
4 , t as (select to_number(to_char(tcol, 'HH24')) as hr
5 from t42)
6 select hrs.hr
7 , count(t.hr)
8 from hrs
9 left outer join t
10 on hrs.hr = t.hr
11 where hrs.hr between 7 and 9
12 group by hrs.hr
13 order by hrs.hr
14 /
HR COUNT(T.HR)
---------- -----------
7 3
8 0
9 1
SQL>
此解决方案假定时间列是Oracle日期数据类型。如果它是一个字符串,那么首先将其转换为日期或应用substr()
将起作用。