2010-11-14 2 views
3

Я пытаюсь проанализировать некоторые веб-журналы с моего веб-сервера. Я запустил все журналы на прошлой неделе в базу данных mysql, и я анализирую журналы.MySQL: подсчитайте количество элементов в диапазоне

Я создал таблицу sessionID с, а продолжительность сеанса, используя эту команду MySQL:

SELECT 
     Log_Analysis_RecordsToSesions.sessionID, 
     ABS(TIMEDIFF(
       MIN(Log_Analysis_Records.date), 
       MAX(Log_Analysis_Records.date) 
     )) as session_length 
FROM 
     Log_Analysis_RecordsToSesions, 
     Log_Analysis_Records 
WHERE 
     Log_Analysis_RecordsToSesions.recordID=Log_Analysis_Records.recordID 
GROUP BY 
     sessionID; 

-

+-----------+----------------+ 
| sessionID | session_length | 
+-----------+----------------+ 
|   1 | 2031.000000 | 
|   2 | 1954.000000 | 
|   3 |  401.000000 | 
... 

То, что я хочу сделать сейчас, это изменить заявление так, что он произведет что-то вроде этого:

Range (time)  Number of Sessions 
0 to 2   10 
2 to 4   4 
4 to 6   60 
... 

Диапазон будет фиксированным количество времени, и я хочу подсчитать количество сеансов в этом диапазоне. Моя первая мысль состоит в том, чтобы перебрать все это с помощью php, но это кажется очень трудоемким и грубым. Есть ли способ сделать это в mysql?

ответ

0

Я отредактировал ваше сообщение, чтобы добавить псевдоним, что делает результаты более удобочитаемыми. Теперь я думаю, что вы могли бы попробовать что-то вроде этого:

SELECT 
     Log_Analysis_RecordsToSesions.sessionID, 
     ABS(TIMEDIFF(
       MIN(Log_Analysis_Records.date), 
       MAX(Log_Analysis_Records.date) 
     )) as session_length, 
     CONCAT(session_length DIV 2, ' to ', session_length DIV 2 + 2) as range 
FROM 
     Log_Analysis_RecordsToSesions, 
     Log_Analysis_Records 
WHERE 
     Log_Analysis_RecordsToSesions.recordID=Log_Analysis_Records.recordID 
GROUP BY 
     range 
ORDER BY session_length; 
0

Вы можете создать еще одну таблицу, назвав его ranges:

CREATE TABLE ranges (
    `range` int 
); 

INSERT INTO ranges VALUES (2), (4), (6), (8); 

Затем вы можете обернуть ваш запрос в качестве производной таблицы, и слева присоединиться к ranges таблицы с производной таблицей:

SELECT CONCAT(r.`range` - 2, ' to ', r.`range`) `range`, 
     COUNT(session_length) number_of_sessions 
FROM  ranges r 
LEFT JOIN (
    SELECT rs.sessionID, 
       ABS(TIMEDIFF(MIN(ar.date), MAX(ar.date))) session_length 
    FROM  Log_Analysis_RecordsToSesions rs, 
    JOIN  Log_Analysis_Records ar ON (rs.recordID = ar.recordID) 
    GROUP BY rs.sessionID; 
) dt ON (dt.session_length > r.`range` - 2 AND 
     dt.session_length <= r.`range`) 
GROUP BY r.`range`; 

Для тестового примера, давайте создадим фиктивную таблицу с кучей произвольной длиной сессии, как в вашем примере:

CREATE TABLE sessions (
    session_id  int, 
    session_length int 
); 

INSERT INTO sessions VALUES (1, 2031); 
INSERT INTO sessions VALUES (2, 1954); 
INSERT INTO sessions VALUES (3, 401); 
INSERT INTO sessions VALUES (4, 7505); 

Тогда мы можем сделать следующее, если предположить, что ranges таблица уже создана:

SELECT CONCAT(r.`range` - 2, ' to ', r.`range`) `range`, 
     COUNT(session_length) number_of_sessions 
FROM  ranges r 
LEFT JOIN (
    SELECT session_id, session_length FROM sessions 
) dt ON (dt.session_length/1000 > r.`range` - 2 AND 
     dt.session_length/1000 <= r.`range`) 
GROUP BY r.`range`; 

Результат:

+--------+--------------------+ 
| range | number_of_sessions | 
+--------+--------------------+ 
| 0 to 2 |     2 | 
| 2 to 4 |     1 | 
| 4 to 6 |     0 | 
| 6 to 8 |     1 | 
+--------+--------------------+ 
4 rows in set (0.00 sec) 
0

Выполнить этот запрос над сгенерированной таблицы:

SELECT 
    CONCAT((session_length div 2000)*2, ' to ', ((session_length+2000) div 2000)*2) AS `Range (time)`, 
    COUNT(*) AS `Number of sessions` 
FROM sessions 
GROUP BY session_length div 2000 
+0

Не могли бы вы объяснить, на второй линии делает? – sixtyfootersdude

+0

Он объединяет значение отображения, которое используется в 'group by', со словом' 'to '' и следующей группой, которая будет использоваться в' group by' (+ 2000 мс). '' '' '' Используется для отображения: поскольку, например, 401 и 1500 div 2000 является '0' (значение, используемое в' group by'), а 2031 div 2000 - '1' - другая группа. –

Смежные вопросы