MySQL:计算范围内的项目数

时间:2010-11-14 19:02:57

标签: mysql

我正在尝试从我的网络服务器分析一些网络日志。我将上周的所有日志推送到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中执行此操作?

3 个答案:

答案 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