SQL / MySQL SELECT и усреднение по определенным значениям - PullRequest
0 голосов
/ 17 марта 2009

Мне нужно работать с инструментом анализа, который измеряет количество обращений веб-службы к серверу в час. Эти измерения заносятся в базу данных. Ниже приведен фрагмент такого измерения:

mysql> SELECT * FROM sample s LIMIT 4;  
+---------+------+-------+  
| service | hour | calls |  
+---------+------+-------+  
| WS04    |   04 |    24 |  
| WS12    |   11 |    89 |  
| WSI64   |   03 |    35 |  
| WSX52   |   01 |    25 |  
+---------+------+-------+  
4 rows in set (0.00 sec)  

В качестве конечного результата я хотел бы знать сумму всех завершенных веб-сервисов в час дня. Очевидно, что это легко сделать с помощью SUM () и GROUP BY:

mysql> SELECT hour, SUM(calls) FROM sample s GROUP BY hour;  
+------+------------+  
| hour | SUM(calls) |  
+------+------------+  
|   00 |        634 |  
|   01 |        642 |  
|   02 |        633 |  
|   03 |        624 |  
|   04 |        420 |  
|   05 |        479 |  
|   06 |        428 |  
|   07 |        424 |  
|   08 |        473 |  
|   09 |        434 |  
|   10 |        485 |  
|   11 |        567 |  
|   12 |        526 |  
|   13 |        513 |  
|   14 |        555 |  
|   15 |        679 |  
|   16 |        624 |  
|   17 |        796 |  
|   18 |        752 |  
|   19 |        843 |  
|   20 |        827 |  
|   21 |        774 |  
|   22 |        647 |  
|   23 |        533 |  
+------+------------+  
12 rows in set (0.00 sec)  

Моя проблема в том, что в старых наборах вызовы веб-службы в часы с [00-11] уже суммировались. Следовательно, простое утверждение, как указано выше, приведет к

mysql> SELECT hour, SUM(calls) FROM sample s GROUP BY hour;  
+------+------------+  
| hour | SUM(calls) |  
+------+------------+  
|   00 |       6243 | <------ sum of hours 00-11!  
|   12 |        526 |  
|   13 |        513 |  
|   14 |        555 |  
|   15 |        679 |  
|   16 |        624 |  
|   17 |        796 |  
|   18 |        752 |  
|   19 |        843 |  
|   20 |        827 |  
|   21 |        774 |  
|   22 |        647 |  
|   23 |        533 |  
+------+------------+  
13 rows in set (0.00 sec)

Это нежелательный результат. Чтобы сделать старые наборы [00,12, ..., 23] сопоставимыми с новыми наборами [00,01, ..., 23], я хотел бы иметь одно утверждение, которое усредняет значение [00] и распределяет его за пропущенные часы, например:

+------+------------+  
| hour | SUM(calls) |  
+------+------------+  
|   00 |    6243/11 |  
|   01 |    6243/11 |  
            [...]  
|   12 |        526 |  
            [...]  
|   23 |        533 |  
+------+------------+

Я легко могу сделать это, используя временные таблицы или представления, но я не знаю, как этого добиться без них.

Есть идеи? Потому что это сводит меня с ума: P

Ответы [ 2 ]

1 голос
/ 17 марта 2009

Для объединения потребуется набор строк с 12 строками.

Наиболее простым решением будет объединение 12 SELECT операторов в объединении:

SELECT  COALESCE(morning.hour, sample.hour), 
        SUM(CASE WHEN morning.hour IS NULL THEN calls ELSE calls / 12 END) AS calls
FROM    sample
LEFT JOIN
        (
        SELECT 0 AS hour
        UNION ALL
        SELECT 1
        ...
        UNION ALL
        SELECT 11
        ) AS morning
ON      sample.hour = 0 AND sample.service IN ('old_service1', 'old_service2')
GROUP BY
        1
1 голос
/ 17 марта 2009

Вероятно, вам лучше всего делать это с временными таблицами / представлениями (я бы рекомендовал просмотр временных таблиц), или вы в конечном итоге получите неприятный для конкретного случая оператор, который со временем станет кошмаром.

...