让我们假设你的表是这样定义的:
CREATE TABLE t
(
id varchar(10), /* possibly a PRIMARY KEY, but not sure */
tnstime timestamp,
/* Don't use a varchar if the list of status is predefined and fixed */
status ENUM ('completed', 'submited', 'failed'),
/* This should be unique in any case, so, let's make it the PK */
PRIMARY KEY (id, tnstime)
) ;
...我们有这些数据:
INSERT INTO t
(id, tnstime, status)
VALUES
('A0', addtime(current_date, time '03:23:00'), 'failed'),
('1', addtime(current_date, time '10:00:00'), 'completed'),
('2', addtime(current_date, time '10:03:00'), 'failed'),
('3', addtime(current_date, time '10:05:00'), 'completed'),
('4', addtime(current_date, time '10:06:00'), 'submited'),
('5', addtime(current_date, time '10:07:00'), 'completed'),
('6', addtime(current_date, time '11:03:00'), 'completed'),
('7', addtime(current_date, time '11:04:00'), 'completed'),
('8', addtime(current_date, time '11:05:00'), 'completed') ;
第一种方法,让我们GROUP BY
小时和地位......
SELECT
EXTRACT(hour FROM tnstime) AS start_hour, status, count(*) AS c0
FROM
t
WHERE
/* Restrict to doday; the < current_date + interval 1 day may not be
needed, because you're supposed to know the future ;-). But just in
case time travel were possible.
Note that current_date is today at 00:00:00. Note also >= and <.
*/
tnstime >= current_date AND tnstime < current_date + interval 1 day
GROUP BY
start_hour, status
ORDER BY
start_hour, status ;
这将提供与结果如下:
start_hour | status | c0
---------: | :-------- | -------:
3 | failed | 1
10 | completed | 3
10 | submited | 1
10 | failed | 1
11 | completed | 3
现在我们转发这些数据,(请注意子查询q
是上一个查询,减去ORDER BY
),并加入了一些细微的格式(concat
,lpad
,...),使它看起来尽可能接近您的要求:
SELECT
concat(lpad(start_hour, 2, '0'), ' - ', lpad(start_hour + 1, 2, '0')) AS hour_interval,
coalesce(sum(CASE WHEN status = 'completed' THEN c0 END), 0) AS completed,
coalesce(sum(CASE WHEN status = 'submited' THEN c0 END), 0) AS submited,
coalesce(sum(CASE WHEN status = 'failed' THEN c0 END), 0) AS failed
FROM
(SELECT
EXTRACT(hour FROM tnstime) AS start_hour, status, count(*) AS c0
FROM
t
WHERE
tnstime >= current_date AND tnstime < (current_date + interval 1 day)
GROUP BY
start_hour, status
) AS q
GROUP BY
hour_interval
ORDER BY
hour_interval ;
注意,3210功能将nulls
(无条目)转换为0。
你会得到以下结果:
hour_interval | completed | submited | failed
:------------ | --------: | -------: | -----:
03 - 04 | 0 | 0 | 1
10 - 11 | 3 | 1 | 1
11 - 12 | 3 | 0 | 0
您可以在dbfiddle检查一切here
参考:
的Oracle或MySQL?为什么java标签? – user7294900
使用HOUR功能剪切时间戳,然后在其上按组合。然后只需使用'COUNT' aggergate。 – Koshinae