繁体   English   中英

选择周围的行php / mysql

[英]Select surrounding rows php/mysql

我想在条件匹配的一行周围选择一组行,即选择一行,然后在它之前和之后返回5条记录。

根据要求提供更多信息(抱歉!)

好的,所以这张桌子记录了比赛的单圈时间。 圈数与用户有关(用户有很多圈)。 我想找到一个用户的最佳圈速,然后从所需用户的最佳圈数之上和之下的UNIQUE用户中找到最佳圈数的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​​。

同样,这是作为灵感的来源。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM