我想在条件匹配的行周围选择一组行,即选择一行,然后在它之前和之后返回 5 条记录。
根据要求提供更多信息(对不起!)
好的,所以表格记录了比赛的单圈时间。圈数与用户相关(用户有很多圈数)。我想为用户找到最佳单圈时间,然后从所需用户的最佳单圈上方和下方的唯一用户中找到 x 次最佳单圈。
这可能吗?
我想在条件匹配的行周围选择一组行,即选择一行,然后在它之前和之后返回 5 条记录。
根据要求提供更多信息(对不起!)
好的,所以表格记录了比赛的单圈时间。圈数与用户相关(用户有很多圈数)。我想为用户找到最佳单圈时间,然后从所需用户的最佳单圈上方和下方的唯一用户中找到 x 次最佳单圈。
这可能吗?
这实际上只是对 PHP-Steven 答案的更正,但我没有足够的代表发表评论。
SELECT `lap_time`, `uid`
FROM `table` t1
WHERE `lap_time` =< 120
AND NOT EXISTS (SELECT 1 FROM `table`
WHERE `uid` = t1.`uid` AND `lap_time` > t1.`lap_time` AND `lap_time` < 120)
ORDER BY `lap_time` DESC
LIMIT 5
和
SELECT `lap_time`, `uid`
FROM `table` t1
WHERE `lap_time` > 120
AND NOT EXISTS (SELECT 1 FROM `table`
WHERE `uid` = t1.`uid` AND `lap_time` < t1.`lap_time` AND `lap_time` > 120)
ORDER BY `lap_time` DESC
LIMIT 5
唯一的区别是NOT EXISTS
用于消除同一用户的第二圈时间的条款。否则,您将获得下一个最慢和最快的 lap_times,而不是下一个最慢/最快的唯一用户。
这需要相当多的黑客攻击,但它似乎对我有用。
SELECT *
FROM `lap_times`
WHERE `id` IN (
SELECT * FROM (
SELECT lt1.id
FROM `lap_times` lt1
WHERE lt1.time = (SELECT MIN(lt2.time) FROM `lap_times` lt2 WHERE lt2.user_id = lt1.user_id)
AND lt1.time <= (SELECT MIN(lt3.time) FROM `lap_times` lt3 WHERE lt3.user_id = 2)
AND lt1.user_id != 2
ORDER BY lt1.time ASC
LIMIT 5
) AS `tbl1`
) OR `id` = (
SELECT `id`
FROM `lap_times`
WHERE `user_id` = 2
ORDER BY `time` ASC
LIMIT 1
) OR `id` IN (
SELECT * FROM (
SELECT lt1.id
FROM `lap_times` lt1
WHERE lt1.time = (SELECT MIN(lt2.time) FROM `lap_times` lt2 WHERE lt2.user_id = lt1.user_id)
AND lt1.time >= (SELECT MIN(lt3.time) FROM `lap_times` lt3 WHERE lt3.user_id = 2)
AND lt1.user_id != 2
ORDER BY lt1.time ASC
LIMIT 5
) AS `tbl2`
)
ORDER BY `time` ASC;
所以我假设你想按圈数排序。
SELECT `lap_time`, `uid`
FROM `table`
WHERE `uid` = x AND `lapnum` = y
这将获得最后一圈的行。可以说它存储为 INT 并且以秒为单位。结果是 120。
现在更快地选择所有单圈时间。
SELECT `lap_time`, `uid`
FROM `table`
WHERE `laptime` =< 120
GROUP BY `uid`
ORDER BY `laptime` DESC
LIMIT 5
最后选择所有较慢的单圈时间。
SELECT `lap_time`, `uid`
FROM `table`
WHERE `laptime` >= 120
GROUP BY `uid`
ORDER BY `laptime` ASC
LIMIT 5
这将为您提供所需的所有 11 行!
它应该是这样的:
lap_time = column with lap times (assumed to be an int or numeric)
laps = table containing lap times
CURRENT_LAP_TIME = the lap time in question
然后
SELECT lap_time FROM laps
WHERE lap_time < CURRENT_LAP_TIME
ORDER BY lap_time DESC LIMIT 5
UNION
SELECT lap_time FROM laps
WHERE lap_time >= CURRENT_LAP_TIME
ORDER BY lap_time LIMIT 6
您可以将整个内容包装在另一个 SELECT 语句中,如果您希望它按特定顺序执行 ORDER BY。(我认为有更好的方法来反转第一个 SELECT 语句,但我想不出它。)
鉴于数据非常稀疏,我只能提供一个非常通用的解决方案。将其视为灵感:
SELECT
id,
fieldX,
ABS(id - <id-to-select>) AS distance
FROM
table
WHERE
ABS(id - <id-to-select>) < 5
ORDER BY
distance DESC
但是,此方法不保证id = <id-to-select>
返回带有的行。它只是将“最近”的行返回到此 ID。
同样,这只是作为灵感的来源。