2017-07-30 39 views
-4

小时算我有表列如下获得SQL

ID(VARCHAR)tnstime(时间戳)状态(VARCHAR)和状态含有如已完成,提交或失败的固定值。

我怎样才能像下面

10 - 11  --- completed 110 submited 24 failed 3 
11 - 12  --- completed 125 submited 36 failed 4 
13 - 14  --- completed 156 submited 37 failed 8 
15 - 16  --- completed 178 submited 26 failed 3 
17 - 18  --- completed 179 submited 29 failed 6​ 
+1

的Oracle或MySQL?为什么java标签? – user7294900

+3

使用HOUR功能剪切时间戳,然后在其上按组合。然后只需使用'COUNT' aggergate。 – Koshinae

回答

0

这会给你不同的状态在不同的行,如果你想在同一行的结果恐怕你必须写在过去的24小时计数一个小程序

SELECT 
DATEPART(HOUR, tnstime) AS START_HOUR, 
DATEPART(HOUR, DATEADD(HOUR, 1, tnstime)) AS END_HOUR 
STATUS, 
COUNT(*) 
FROM YOUR_TABLE 
GROUP BY DATEPART(HOUR, tnstime),DATEPART(HOUR, DATEADD(HOUR, 1, tnstime)), STATUS 
0

让我们假设你的表是这样定义的:

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),并加入了一些细微的格式(concatlpad,...),使它看起来尽可能接近您的要求:

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


参考:

+0

start_hour + 1会给你一个23-24的间隔,否则你应该在时间戳上加1小时。 –

+0

是的,这是对的......使用你的命名约定。如果你愿意,你可以使用一个案件,并有23 - 00。 – joanolo