2012-05-03 17 views
13

私は履歴テーブルから毎時の使用状況レポートを取得しようとしています。 historyテーブルです。時間単位のMySQLグループ

CREATE TABLE IF NOT EXISTS `history` (
`history_id` int(11) unsigned NOT NULL AUTO_INCREMENT, 
`user_id` int(11) unsigned NOT NULL DEFAULT '0', 
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
PRIMARY KEY (`history_id`), 
KEY `user_id` (`user_id`), 
KEY `created` (`created`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; 

私はHOURCOUNTによってグループに与えられた日付範囲内のすべてのレコードをしたいです。

Hours   | Usage 
------------------------------------ 
00:00-01:00  |  5 
01:00-02:00  |  9 
02:00-03:00  |  0 (or NULL) 
03:00-04:00  |  20 
... 
... 
... 
22:00-23:00  |  11 
23:00-00:00  |  1 

私はこのようなクエリを使用しましたが、すべての時間を表示しません。

SELECT 

CASE 
    WHEN HOUR(created) BETWEEN 0 AND 1 THEN '00:00 - 01:00' 
    WHEN HOUR(created) BETWEEN 1 AND 2 THEN '01:00 - 02:00' 
    WHEN HOUR(created) BETWEEN 2 AND 3 THEN '02:00 - 03:00' 
    WHEN HOUR(created) BETWEEN 3 AND 4 THEN '03:00 - 04:00' 
    WHEN HOUR(created) BETWEEN 4 AND 5 THEN '04:00 - 05:00' 
    WHEN HOUR(created) BETWEEN 5 AND 6 THEN '05:00 - 06:00' 
    WHEN HOUR(created) BETWEEN 6 AND 7 THEN '06:00 - 07:00' 
    WHEN HOUR(created) BETWEEN 7 AND 8 THEN '07:00 - 08:00' 
    WHEN HOUR(created) BETWEEN 8 AND 9 THEN '08:00 - 09:00' 
    WHEN HOUR(created) BETWEEN 9 AND 10 THEN '09:00 - 10:00' 
    WHEN HOUR(created) BETWEEN 10 AND 11 THEN '10:00 - 11:00' 
    WHEN HOUR(created) BETWEEN 11 AND 12 THEN '11:00 - 12:00' 
    WHEN HOUR(created) BETWEEN 12 AND 13 THEN '12:00 - 13:00' 
    WHEN HOUR(created) BETWEEN 13 AND 14 THEN '13:00 - 14:00' 
    WHEN HOUR(created) BETWEEN 14 AND 15 THEN '14:00 - 15:00' 
    WHEN HOUR(created) BETWEEN 15 AND 16 THEN '15:00 - 16:00' 
    WHEN HOUR(created) BETWEEN 16 AND 17 THEN '16:00 - 17:00' 
    WHEN HOUR(created) BETWEEN 17 AND 18 THEN '17:00 - 18:00' 
    WHEN HOUR(created) BETWEEN 18 AND 19 THEN '18:00 - 19:00' 
    WHEN HOUR(created) BETWEEN 19 AND 20 THEN '19:00 - 20:00' 
    WHEN HOUR(created) BETWEEN 20 AND 21 THEN '20:00 - 21:00' 
    WHEN HOUR(created) BETWEEN 21 AND 22 THEN '21:00 - 23:00' 
    WHEN HOUR(created) BETWEEN 22 AND 23 THEN '22:00 - 23:00' 
    WHEN HOUR(created) BETWEEN 23 AND 24 THEN '23:00 - 00:00' 
END AS `Hours`, 

COUNT(*) AS `usage` 
FROM history 
WHERE (created BETWEEN '2012-02-07' AND NOW()) 
GROUP BY 
    CASE 
    WHEN HOUR(created) BETWEEN 0 AND 1 THEN 1 
    WHEN HOUR(created) BETWEEN 1 AND 2 THEN 2 
    WHEN HOUR(created) BETWEEN 2 AND 3 THEN 3 
    WHEN HOUR(created) BETWEEN 3 AND 4 THEN 4 
    WHEN HOUR(created) BETWEEN 4 AND 5 THEN 5 
    WHEN HOUR(created) BETWEEN 5 AND 6 THEN 6 
    WHEN HOUR(created) BETWEEN 6 AND 7 THEN 7 
    WHEN HOUR(created) BETWEEN 7 AND 8 THEN 8 
    WHEN HOUR(created) BETWEEN 8 AND 9 THEN 9 
    WHEN HOUR(created) BETWEEN 9 AND 10 THEN 10 
    WHEN HOUR(created) BETWEEN 10 AND 11 THEN 11 
    WHEN HOUR(created) BETWEEN 11 AND 12 THEN 12 
    WHEN HOUR(created) BETWEEN 12 AND 13 THEN 13 
    WHEN HOUR(created) BETWEEN 13 AND 14 THEN 14 
    WHEN HOUR(created) BETWEEN 14 AND 15 THEN 15 
    WHEN HOUR(created) BETWEEN 15 AND 16 THEN 16 
    WHEN HOUR(created) BETWEEN 16 AND 17 THEN 17 
    WHEN HOUR(created) BETWEEN 17 AND 18 THEN 18 
    WHEN HOUR(created) BETWEEN 18 AND 19 THEN 19 
    WHEN HOUR(created) BETWEEN 19 AND 20 THEN 20 
    WHEN HOUR(created) BETWEEN 20 AND 21 THEN 21 
    WHEN HOUR(created) BETWEEN 21 AND 22 THEN 22 
    WHEN HOUR(created) BETWEEN 22 AND 23 THEN 23 
    WHEN HOUR(created) BETWEEN 23 AND 24 THEN 24 
END 

レコードがある場合のみ表示されます。

Hours   | Usage 
------------------------------------ 
00:00-01:00  |  5 
01:00-02:00  |  9 
23:00-00:00  |  1 
+0

すべての時間を含む一時テーブルを作成し、実際のデータと結合します。 –

答えて

22

あなたの既存のクエリをに減らすことができます。データがないいるものも含め、すべての時間を表示するには

SELECT CONCAT(HOUR(created), ':00-', HOUR(created)+1, ':00') AS Hours 
    ,  COUNT(*) AS `usage` 
FROM  history 
WHERE created BETWEEN '2012-02-07' AND NOW() 
GROUP BY HOUR(created) 

、あなたは外に必要なすべての時間を含むテーブルと結合あなたにはデータが必要です。あなたUNIONを使用して、クエリで、このようなテーブルを作成することができます

SELECT CONCAT(Hour, ':00-', Hour+1, ':00') AS Hours 
    ,  COUNT(created) AS `usage` 
FROM  history 
    RIGHT JOIN (
        SELECT 0 AS Hour 
     UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 
     UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 
     UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 
     UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12 
     UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15 
     UNION ALL SELECT 16 UNION ALL SELECT 17 UNION ALL SELECT 18 
     UNION ALL SELECT 19 UNION ALL SELECT 20 UNION ALL SELECT 21 
     UNION ALL SELECT 22 UNION ALL SELECT 23 
)  AS AllHours ON HOUR(created) = Hour 
WHERE created BETWEEN '2012-02-07' AND NOW() OR created IS NULL 
GROUP BY Hour 
ORDER BY Hour 

しかし、何もデータが存在しないグループの治療は本当に最良のあなたのデータアクセス層ではなく、データベースに配置されたのビジネスロジックの問題ですそれ自身:実際には、アプリケーションが1時間が不在のときは常に0の値を使用することは些細なことです。列TSとログテーブルを考える

+1

2番目のクエリは1時間ごとに表示されず、レコード(または使用率> 0)がある場合にのみ表示されます。何か不足していますか? –

+0

@BurakErdem:申し訳ありませんが、「作成されたIS NULL」のレコードを含める必要があります(つまり、その時間範囲に履歴がない場合)。上記の私の改訂版を参照してください。 – eggyal

+0

これは素晴らしい動作します。どうもありがとうございます... –

0

は、以下では、最後の24時間の時間単位の平均(各時間を仮定すると、少なくとも一つの行を有する)を得るであろう。 は、AVG()を受け入れるものである一方

SELECT 
    FROM_UNIXTIME(TRUNCATE(UNIX_TIMESTAMP(`ts`)/3600, 0) * 3600) as h, 
    AVG(`value`) as v, 
    COUNT(*) as q 
FROM 
    Log 
GROUP BY 
    h 
ORDER BY 
    h desc 
LIMIT 
    24 

カラムTSは、タイムスタンプまたは日時の列であってもよいです。

関連する問題