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

Mysql 如何在不同行上的日期之间获取记录?,mysql,Mysql,我有一个名为Event的表,它记录多玩家服务器上的玩家登录和注销时的情况 +----------------------------------------------+ | id | username | type | timestamp | +----------------------------------------------+ | 1 | Player3 | login | 2014-01-14 17:00:00 | | 2 | Player4 |

我有一个名为
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
在线,它应该返回:
Player1
Player3

到目前为止,我所尝试的:

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');

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

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;
选择用户名,
最大值(类型为'login'和时间戳时的情况)
您可以将时间戳配对为intime和outtime,然后查看指定的时间是否介于这两个时间之间

或者您可以使用
HAVING
取出1级子查询

SELECT username,timestamp as intime,
 (SELECT min(timestamp)
 FROM event e2
 WHERE e2.username = e1.username
 AND e2.timestamp > e1.timestamp
 AND e2.type = 'logout') as outtime
FROM event e1
WHERE e1.type = 'login'
HAVING '2014-01-14 18:00:00' BETWEEN intime AND outtime;

谢谢!我希望登录/注销记录是准确的。但是,如果表中有很多记录,哪一个性能更好?这两个查询的性能应该类似。您可以通过在
timestamp
上放置索引并在第一个版本中添加where子句来提高性能,例如
where timestamp在'201之间4-01-13'和'2014-01-14 18:00:00'
(假设用户登录时间不超过42小时)。这将显著减少数据量。您能看一下我的编辑吗?我有另一个名为Session的表,从该表中查询是否更好?
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;
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';
SELECT username FROM
(SELECT username,timestamp as intime,
       (SELECT min(timestamp)
        FROM event e2
        WHERE e2.username = e1.username
          AND e2.timestamp > e1.timestamp
        AND e2.type = 'logout') as outtime
FROM event e1
WHERE e1.type = 'login'
)t1
WHERE '2014-01-14 18:00:00' BETWEEN t1.intime AND t1.outtime;
SELECT username,timestamp as intime,
 (SELECT min(timestamp)
 FROM event e2
 WHERE e2.username = e1.username
 AND e2.timestamp > e1.timestamp
 AND e2.type = 'logout') as outtime
FROM event e1
WHERE e1.type = 'login'
HAVING '2014-01-14 18:00:00' BETWEEN intime AND outtime;