Выделите окружающие строки php / mysql - PullRequest
2 голосов
/ 03 декабря 2009

Я хочу выбрать группу строк вокруг строки, соответствующей условиям, т.е. выбрать строку и затем вернуть 5 записей до и после нее.

Больше информации по запросу (извините, но!)

Хорошо, значит, в таблице записано время круга из гонки. Колени связаны с пользователями (у пользователей много кругов). Я хочу найти лучшее время круга для пользователя, а затем x количество лучших кругов от УНИКАЛЬНЫХ пользователей выше И ниже требуемого лучшего круга пользователя.

Возможно ли это?

Ответы [ 5 ]

3 голосов
/ 19 декабря 2009

Это действительно просто исправление ответа 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, которые служат для исключения времени вторичного круга одним и тем же пользователем. В противном случае вы получите следующих самых медленных и быстрых кругов, но не следующих самых медленных / быстрых уникальных пользователей.

2 голосов
/ 08 декабря 2009

Это заняло немало взлома, но, похоже, с моей стороны работает.


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 &lt= (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;

1 голос
/ 26 января 2010

Это должно быть что-то вроде:

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, но я не могу думать об этом с головы до ног.)

1 голос
/ 08 декабря 2009

Итак, я предполагаю, что вы хотите отсортировать по времени круга.


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 строк, которые вам нужны!

0 голосов
/ 03 декабря 2009

Учитывая очень скудные данные, я могу предоставить только очень общее решение. Думайте об этом как о вдохновении:

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> будет возвращена. Он просто возвращает строку «ближайший» к этому идентификатору.

Опять же, это только , предназначенный в качестве источника вдохновения.

...