2009-12-03 5 views
2

조건에 맞는 행 주위의 행 그룹을 선택하고 싶습니다. 즉, 행을 선택하고 그 전후에 5 개의 레코드를 리턴하고 싶습니다.주위의 행을 선택하십시오 PHP/mysql

더 많은 정보

확인 (! 한판 승부 죄송합니다) 요청, 그래서 테이블 레코드는 경주에서 배를 무릎으로. 랩은 사용자와 관련이 있습니다 (사용자는 많은 랩을가집니다). 나는 사용자를위한 최상의 랩타임을 찾고, 그 다음에 요구되는 사용자의 최상의 랩보다 위의 UNIQUE 사용자의 x 랩 수를 찾아야한다.

이것이 가능합니까?

+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>와 행이 반환됩니다 하지을 보장하는 것은 아닙니다. 이 ID에 "가장 가까운"행만 반환합니다.

다시 말하지만, 이것은 인데, 영감의 원천으로 사용 된 것은입니다.

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를 얻지 만 다음으로 가장 느리고 가장 빠른 순 사용자는 얻지 못합니다.

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 문에서 모든 일을 마무리하고 특정 순서를 원하는 경우에 의해 주문을 수행 할 수 있습니다

1

그것은 무언가 같이해야합니다.(첫 번째 SELECT 문을 뒤집을 수있는 더 좋은 방법이 있다고 생각하지만 머리 위로 생각할 수 없다.)

관련 문제