2017-07-30 52 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