我有一张表:
ID TIMEVALUE
----- -------------
1 06.07.15 06:43:01,000000000
2 06.07.15 12:17:01,000000000
3 06.07.15 18:21:01,000000000
4 06.07.15 23:56:01,000000000
5 07.07.15 04:11:01,000000000
6 07.07.15 10:47:01,000000000
7 07.07.15 12:32:01,000000000
8 07.07.15 14:47:01,000000000
我希望特殊时间对这些数据进行分组 我当前的查询如下所示:
SELECT TO_CHAR(TIMEVALUE, 'YYYY\MM\DD'), COUNT(ID),
SUM(CASE WHEN TO_CHAR(TIMEVALUE, 'HH24MI') <=700 THEN 1 ELSE 0 END) as morning,
SUM(CASE WHEN TO_CHAR(TIMEVALUE, 'HH24MI') >700 AND TO_CHAR(TIMEVALUE, 'HH24MI') <1400 THEN 1 ELSE 0 END) as daytime,
SUM(CASE WHEN TO_CHAR(TIMEVALUE, 'HH24MI') >=1400 THEN 1 ELSE 0 END) as evening FROM Table
WHERE TIMEVALUE >= to_timestamp('05.07.2015','DD.MM.YYYY')
GROUP BY TO_CHAR(TIMEVALUE, 'YYYY\MM\DD')
我得到了这个输出
day overall morning daytime evening
----- ---------
2015\07\05 454 0 0 454
2015\07\06 599 113 250 236
2015\07\07 404 139 265 0
因此在同一天(0-7点,7-14点和14-24点)进行精细分组 但我现在的问题是: 如何在午夜进行分组?
例如,从第二天的6-14,14-23和23-6算起。
我希望你理解我的问题。如果有更好的解决方案,欢迎您甚至改进我的上层查询。
答案 0 :(得分:1)
编辑:现在已经过测试:SQL Fiddle
关键是调整group by
,以便在早上6点之前的任何内容与前一天分组。在那之后,计数非常简单。
SELECT TO_CHAR(CASE WHEN EXTRACT(HOUR FROM timevalue) < 6
THEN timevalue - 1
ELSE timevalue
END, 'YYYY\MM\DD') AS day,
COUNT(*) AS overall,
SUM(CASE WHEN EXTRACT(HOUR FROM timevalue) >= 6 AND EXTRACT(HOUR FROM timevalue) < 14
THEN 1 ELSE 0 END) AS morning,
SUM(CASE WHEN EXTRACT(HOUR FROM timevalue) >= 14 AND EXTRACT(HOUR FROM timevalue) < 23
THEN 1 ELSE 0 END) AS daytime,
SUM(CASE WHEN EXTRACT(HOUR FROM timevalue) < 6 OR EXTRACT(HOUR FROM timevalue) >= 23
THEN 1 ELSE 0 END) AS evening
FROM my_table
WHERE timevalue >= TO_TIMESTAMP('05.07.2015','DD.MM.YYYY')
GROUP BY TO_CHAR(CASE WHEN EXTRACT(HOUR FROM timevalue) < 6
THEN timevalue - 1
ELSE timevalue
END, 'YYYY\MM\DD');
答案 1 :(得分:1)
从时间值减去1天,首先是低于'06:00'的时间,然后是:
select TO_CHAR(day, 'YYYY\MM\DD') day, COUNT(ID) cnt,
SUM(case when '23' < tvh or tvh <= '06' THEN 1 ELSE 0 END) as midnight,
SUM(case when '06' < tvh and tvh <= '14' THEN 1 ELSE 0 END) as daytime,
SUM(case when '14' < tvh and tvh <= '23' THEN 1 ELSE 0 END) as evening
FROM (
select id, to_char(TIMEVALUE, 'HH24') tvh,
trunc(case when (to_char(timevalue, 'hh24') <= '06')
then timevalue - interval '1' day
else timevalue end) day
from t1
)
GROUP BY day
答案 2 :(得分:0)
也许你可以这样做(有些重新格式化或PIVOT):
WITH spans AS
(SELECT TIMESTAMP '2015-01-01 00:00:00' + LEVEL * INTERVAL '1' HOUR AS start_time
FROM dual
CONNECT BY TIMESTAMP '2015-01-01 00:00:00' + LEVEL * INTERVAL '1' HOUR < LOCALTIMESTAMP),
t AS
(SELECT start_time, lead(start_time, 1) OVER (ORDER BY start_time) AS end_time, ROWNUM AS N
FROM spans
WHERE EXTRACT(HOUR FROM start_time) IN (6,14,23))
SELECT N, start_time, end_time, COUNT(*) AS ID_COUNT,
DECODE(EXTRACT(HOUR FROM start_time), 6,'morning', 14,'daytime', 23,'evening') AS daytime
FROM t
JOIN YOUR_TABLE WHERE TIMEVALUE BETWEEN start_time AND end_time
GROUP BY N;
当然,初始时间值(我的示例中为“2015-01-01 00:00:00”)必须低于表格中的最小日期。