2016-09-19 5 views
1

다른 트랙에서 경주하는 수많은 자동차 운전자가 있습니다. 나는 각각의 특정 트랙에서 가장 좋은 랩타임을 얻고 싶고, 특정 트랙에서 가장 좋은 랩타임을 다른 유저들과 비교하여 순위를 매길 원한다. 모든 트랙에서 모든 사용자에게이 작업을 수행하려고합니다. 그래서 큰 리더 보드를 돌려주고 싶습니다.사용자의 최저 랩타임 순위를 찾으십시오.

기본적으로, 트랙 1에 25 바퀴를 완주 한 10 명의 경주 용 자동차 드라이버가 있다면, 각 경주 용 자동차 드라이버의 최상의 랩타임 만 확인하고 각 트랙에서 그 시간을 서로 비교합니다. http://sqlfiddle.com/#!9/64d6c/2

, 당신은 모든 조각이 있는지 확인하려면 "tracks.verified"열이도있다 :

은 나는 거의 그것을 가지고 아래의 쿼리와 SQLFiddle 링크를 참조 생각합니다. 이것은 트랙이 검증되었는지 여부를 결정합니다. 이 매개 변수에 대해 실제로 걱정할 필요가 없으며 원하는 경우 생략 할 수 있습니다. 나는이 라인을 말하는 겁니다 :

AND s1.track_id IN (SELECT id FROM tracks WHERE verified=1) 

http://sqlfiddle.com/#!9/64d6c/2

SELECT track_id, user_id, duration, @rank := @rank + 1 AS rank FROM 
(
    SELECT DISTINCT s1.track_id, s1.user_id, s1.duration 
    FROM session_lap_times s1 
    LEFT JOIN session_lap_times s2 
    ON s1.user_id=s2.user_id 
    AND s1.track_id = s2.track_id 
    AND s1.duration > s2.duration 
    WHERE s2.duration IS NULL 
    AND s1.track_id IN (SELECT id FROM tracks WHERE verified=1) 
    ORDER BY s1.duration ASC 
) zz, (SELECT @rank := 0) z; 

이 출력 :

+----------+---------+------------------+------+ 
| track_id | user_id | duration   | rank | 
+----------+---------+------------------+------+ 
|  15 |  2 | 71001.5129995350 | 1 | 
|  15 |  1 | 75001.5129995350 | 2 | 
|  17 |  1 | 90258.1180334090 | 3 | 
|  17 |  2 | 90897.0659971240 | 4 | 
+----------+---------+------------------+------+ 

문제는 서로에 대해 모든 순위가되고, 그리고 각 트랙의 모든에 대한 . 이러한 결과는 다음과 같아야합니다

+----------+---------+------------------+------+ 
| track_id | user_id | duration   | rank | 
+----------+---------+------------------+------+ 
|  15 |  2 | 71001.5129995350 | 1 | 
|  15 |  1 | 75001.5129995350 | 2 | 
|  17 |  1 | 90258.1180334090 | 1 | 
|  17 |  2 | 90897.0659971240 | 2 | 
+----------+---------+------------------+------+ 

내가이 줄 문제라고 생각합니다 :

AND s1.track_id IN (SELECT id FROM tracks WHERE verified=1) 

때문에 나는 넣으면 s1.track_id = 15 하나의 예상대로 (예를 들어)이 작동 선로. 그들 모두는 아닙니다.

도움을 주시면 감사하겠습니다.

편집 :

결과를 user_id (으)로 필터링하려고합니다. 그래서 전체 쿼리를 가져 와서 하위 쿼리에 넣었습니다. 하위 쿼리에 넣지 않고이 작업을 수행 할 수있는 방법이 있습니까? 쿼리 내가있어 드라이버의 총 수를 계산에 관해서는

select track_id, user_id, duration, rank from (SELECT track_id, user_id,duration, 
    CASE WHEN [email protected] THEN @rank:=0 END as reset, 
    @rank := @rank + 1 AS rank, 
    @track:=track_id 
FROM 
(
    SELECT DISTINCT s1.track_id, s1.user_id, s1.duration 
    FROM session_lap_times s1 
    LEFT JOIN session_lap_times s2 
    ON s1.user_id=s2.user_id 
    AND s1.track_id = s2.track_id 
    AND s1.duration > s2.duration 
    WHERE s2.duration IS NULL 
    AND s1.track_id IN (SELECT id FROM tracks WHERE verified=1) 
    ORDER BY s1.duration ASC 
) zz, (SELECT @rank := 0, @track := null) z) as x where user_id=1 

감사

: 다시

SELECT track_id, COUNT(user_id) FROM (SELECT track_id,user_id FROM session_lap_times GROUP BY track_id,user_id) as z GROUP BY track_id 

, 부질없이이 일을 더 좋은 방법은 무엇입니까? 감사! :)

답변

1
SELECT track_id, user_id, duration, 
    CASE WHEN [email protected] THEN @rank:=0 END as reset, 
    @rank := @rank + 1 AS rank, 
    @track:=track_id 
FROM 
(
    SELECT DISTINCT s1.track_id, s1.user_id, s1.duration 
    FROM session_lap_times s1 
    LEFT JOIN session_lap_times s2 
    ON s1.user_id=s2.user_id 
    AND s1.track_id = s2.track_id 
    AND s1.duration > s2.duration 
    WHERE s2.duration IS NULL 
    AND s1.track_id IN (SELECT id FROM tracks WHERE verified=1) 
    ORDER BY s1.duration ASC 
) zz, (SELECT @rank := 0, @track := null) z; 

피들로 테스트되었습니다.

은 추가 변수를 소개하고 track_id 변화 나는 당신의 SQL 혼란을 찾을

+0

OH 와우. 굉장해 !! "out of"값을 리턴 할 수 있습니까? 그 궤도에서 경쟁 한 모든 운전자의 합계? 그래서 내 애플 리케이션에 이런 식으로 뭔가를 표시 할 수 있습니다 : 2000 드라이버 중 1 순위? 동일한 쿼리에서이 작업을 수행하는 것이 적절하지 않은 경우 및 자체 쿼리를 사용해야하는 경우 알려주십시오. – toast

+0

추가로 생각한 후에는 별도의 쿼리에서 더 쉽게 수행 할 수 있다고 생각합니다. 나중에 내 앱 코드에서 결과를 일치시킵니다. 이 작업을 수행 할 수있는 쿼리를 알고 있습니까? 감사! – toast

+0

게시 한 원래 쿼리에서 user_id로 결과를 필터링하는 방법이 있습니까? 예를 들어, user_id 1은 track_id 17에서 1 등급을, track_id 15에서 2 등급을 가져야합니다. – toast

0

rank를 재설정합니다. 나는 GROUP BY를 사용할 것이다.

SELECT track_id, user_id, MIN(duration) as best_time 
FROM session_lap_times 
GROUP BY track_id, user_id 
ORDER BY track_id, best_time;