mysql> desc accounts_users;
+------------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| login_at | datetime | YES | | NULL | |
| logout_at | datetime | YES | | NULL | |
+------------------------+--------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
mysql> desc rooms_events;
+------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | MUL | NULL | |
| event | varchar(255) | NO | MUL | NULL | |
| created_at | datetime | YES | | NULL | |
+------------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
当用户执行操作时,我向rooms_events表添加“event”行。事件列可以是“创建”或“销毁”。没有唯一的列。
我想查询:
查找最新事件所在的所有唯一user_id “创建”AND尚未登录(login_at)24小时。
如何执行此类查询?
答案 0 :(得分:1)
我会说可以这样查询:
SELECT DISTINCT U.id
FROM accounts_users U
INNER JOIN rooms_events E ON U.id = E.user_id
WHERE U.login_at < DATE_SUB(NOW(),INTERVAL 24 HOUR)
AND E.created_at IN (
SELECT MAX(created_at)
FROM rooms_events
GROUP BY user_id
)
AND E.`event` = 'create';
我不是100%确定子查询在各种可能的情况下都能完成它的工作,但是有一些测试数据可以在我的机器上运行。
答案 1 :(得分:0)
SELECT user_id
FROM rooms_events c
WHERE NOT EXISTS (
SELECT *
FROM room_events
WHERE event = 'create'
AND user_id = c.user_id
AND created_at > c.created_at )
AND NOT EXISTS (
SELECT *
FROM accounts_users
WHERE id = c.user_id
AND login_at > NOW() - INTERVAL 24 HOUR;
指数:
room_events: INDEX(event, user_id, created_at)
这假设created_at
是event
的时间。
由于您似乎只记录了最新的登录信息,因此可以简化为:
SELECT u.id
FROM rooms_events c
JOIN account_users u ON c.user_id = u.id
WHERE u.login_at < NOW() - INTERVAL 24 HOUR
AND NOT EXISTS (
SELECT *
FROM room_events
WHERE event = 'create'
AND user_id = c.user_id
AND created_at > c.created_at )
如果您希望有大量旧数据,那么INDEX(login_at, id)
可能会有所帮助。
如果event
只能是两个值,请考虑ENUM('create', 'destroy') NOT NULL
。
对于room_events
,(user_id, event)
不是唯一的吗?因此它可能是PRIMARY KEY
(并且摆脱id
)。如果进行了更改,则不需要我建议的索引。