2009-12-03 4 views
2

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

Более подробную информацию по запросу (жаль, что бой!)

Итак, записи в таблице плещутся раз из гонки. Круги связаны с пользователями (у пользователей много кругов). Я хочу найти лучшее время круга для пользователя, а затем - количество лучших кругов от пользователей UNIQUE выше И ниже требуемого лучшего круга пользователя.

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

+5

Пожалуйста, разместите свой запрос и структуру таблицы (или данные примера). – jensgram

+0

Должны ли предыдущие и последующие строки соответствовать исходным критериям SELECT или просто предшествовать и следовать строке SELECT в исходной таблице? –

+1

Просьба также указать, что означает «раньше» и «после», что точно означает (критерии сортировки). – VolkerK

ответ

0

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

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

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

1

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


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

+1

Это может вернуть несколько записей коленей для одного пользователя. Требование состоит в том, чтобы вернуть список уникальных пользователей с их лучшим временем круга. –

+0

Спасибо @vincebowdren. Я добавил GROUP BY, чтобы исправить эту проблему. – Slashterix

2

Это заняло довольно много хакеров, но, похоже, он работает на моем конце.

 

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; 
 
3

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

1

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

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

Смежные вопросы