我有一个名为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/