mysql - 如何获取不同行上日期之间的记录?

标签 mysql

SQL Fiddle

我有一个名为Event的表,用于记录多人服务器上的玩家登录和注销的时间。

+----------------------------------------------+
| id | username | type   | timestamp           |
+----------------------------------------------+
| 1  | Player3  | login  | 2014-01-14 17:00:00 |
| 2  | Player4  | login  | 2014-01-14 17:00:00 |
| 3  | Player4  | logout | 2014-01-14 17:30:00 |
| 4  | Player1  | login  | 2014-01-14 18:00:00 |
| 5  | Player2  | login  | 2014-01-14 19:00:00 |
| 6  | Player3  | logout | 2014-01-14 19:00:00 |
| 7  | Player1  | logout | 2014-01-14 20:00:00 |
| 8  | Player2  | logout | 2014-01-14 20:00:00 |
+----------------------------------------------+

我想获取在特定时间戳在线的用户的唯一用户名列表。例如,如果我想知道谁在 2014-01-14 18:00:00 在线,它应该返回: 玩家1玩家3

到目前为止我已经尝试过:

SELECT * FROM event 
WHERE (timestamp <= '2014-01-14 18:00:00' AND type = 'login')
AND (timestamp >= '2014-01-14 18:00:00' AND type = 'logout');

编辑2:

session 表:

+------------------------------------------------------+
| id | login_event | logout_event | duration (seconds) |
+------------------------------------------------------+
| 1  | 1           | 6            | xxxxxx             |
| 2  | 2           | 3            | xxxxxx             |
| 3  | 4           | 7            | xxxxxx             |
| 4  | 5           | 8            | xxxxxx             |
+------------------------------------------------------+

最佳答案

这比您的查询更复杂。您需要当时最近的操作是登录的人员,本质上是:

SELECT username,
       max(case when type = 'login' and timestamp <= '2014-01-14 18:00:00'
                then timestamp
           end) as lastlogin,
       max(case when type = 'logout' and timestamp <= '2014-01-14 18:00:00'
                then timestamp
           end) as lastlogout
FROM event 
GROUP BY username
HAVING (lastlogout is null or lastlogout < lastlogin) and lastlogin is not null;

编辑:

顺便说一句,如果您知道登录/注销记录完全准确(从未错过,从未重复),您也可以通过计数来执行此操作(有些人可能会发现更容易遵循):

SELECT username,
       sum(type = 'login' and timestamp <= '2014-01-14 18:00:00') as numlogins,
       sum(type = 'logout' and timestamp <= '2014-01-14 18:00:00') as numlogouts
FROM event 
GROUP BY username
HAVING numlogins > numlogouts;

编辑(在 session 中):

session 表上的查询看起来更容易:

SELECT lie.username
from session s join
     event lie
     on s.login_event = lie.id join
     event loe
     on s.logout_event = loe.id
where lie.timestamp <= '2014-01-14 18:00:00' and
      loe.timestamp >= '2014-01-14 18:00:00';

这很有效,并且在小 table 上可能会更好。在较大的 table 上,我认为它不会那么有效。有效的是一个 session 表,其中包含两个时间戳,并在它们上有一个索引。

关于mysql - 如何获取不同行上日期之间的记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21222009/

相关文章:

MySQL 的 C++ 连接器

带有条件的多个表的 mySQL Left Join

mysql - 汇总mysql中的许多表

php - 如何验证 php post 变量?

php - 使用 Eloquent 获取具有多个 ID 的多行

mysql - 无法更新 mysql 表中的位

mysql - 如何避免sql查询中出现多余的引号

MySQL LINQ to SQL 提供程序 Visual Studio 2012

mysql - 如何使用 MYSQL 将字段中的值与 JSON 中的数组相加?

mysql - 查询中的问题。不工作