我正在尝试从我的网络服务器分析一些网络日志。我将上周的所有日志推送到mysql数据库,我正在分析日志。
我使用这个mysql命令生成了一个sessionID
s表和会话长度:
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 :(得分: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;
答案 1 :(得分: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)
答案 2 :(得分: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