假设下表:
user, timestamp, status_code
1, 2017-08-21 09:03:50, 404
2, 2017-08-21 09:03:48, 200
1, 2017-08-21 09:03:45, 404
1, 2017-08-21 09:03:42, 404
1, 2017-08-21 09:03:41, 200
1, 2017-08-21 09:03:40, 404
如何为该用户选择200首次发生的404限制用户的所有条目:
SELECT * FROM tbl WHERE user = 1 ORDER BY timestamp DESC ... ???
预期结果:
user, timestamp, status_code
1, 2017-08-21 09:03:50, 404
1, 2017-08-21 09:03:45, 404
1, 2017-08-21 09:03:42, 404
答案 0 :(得分:2)
您可以使用相关的子查询来获取此信息。
select * from tbl t1
where timestamp > (select t2.timestamp
from tbl t2
where t1.user_id=t2.user_id and t2.status_code=200
order by t2.timestamp
limit 1)
and status_code=404
答案 1 :(得分:0)
使用子查询:
SELECT tbl.* FROM tbl,
(SELECT user, MIN(timestamp) AS min_ts
FROM tbl
WHERE status_code = 200
GROUP BY user
) AS subtable
WHERE status_code = 404
AND tbl.user = subtable.user
AND tbl.timestamp > subtable.min_ts
ORDER BY timestamp DESC
答案 2 :(得分:0)
我将您的查询解释为查找状态为404且时间戳早于同一用户状态为200的任何行的所有行。
我通过颠倒逻辑来考虑这一点:尝试将每个404行连接到状态为200的同一用户的前一行,如果没有找到,那么404行是您要选择的行。如果找不到这样的行,则外连接将使连接行的所有列都为NULL。
select t1.*
from tbl as t1
left outer join tbl as t2
on t2.status_code = 200
and t1.user_id = t2.user_id
and t1.timestamp > t2.timestamp
where t1.status_code = 404
and t2.user_id is NULL -- i.e. when the outer join finds no match
按顺序对列(status_code,user_id,timestamp)的索引将有助于优化t1的WHERE条件和t2的JOIN条件。
从逻辑上讲,我的回答类似于Vamsi Prabhala的回答,但我的回答是使用连接而不是相关的子查询,因此我应该更容易优化。