запрос 1-го, 2-го, 3-го места с разрыва связи с использованием 2-го и 3-го наименьшего с каждым разом в одной строке - PullRequest
2 голосов
/ 29 июня 2011

Я пытаюсь получить тройку самых быстрых по идентификатору и, если есть ничья, использовать 2-е и 3-е самое быстрое время в качестве ничьей.Таким образом, в приведенном ниже примере 3 и 5 связаны третьим самым быстрым временем, но 3 имеет второе самое быстрое время между двумя.

Предпочтительно, чтобы результаты показывали 1-й, 2-й и 3-й раз для каждого идентификатора и были упорядочены1-й самый быстрый, а затем 2-й и 3-й самый быстрый для каждого идентификатора.

Таким образом, таблица выглядит следующим образом:

 ID | TIME
----|-------  
 1  |  6.45  
 2  |  12.43  
 1  |  4.52  
 4  |  16.24  
 5  |  9.43  
 2  |  10.46  
 2  |  8.46  
 3  |  17.49  
 4  |  20.46  
 3  |  16.49  
 5  |  16.97  
 3  |  9.43  
 1  |  25.77  

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

Желаемый результат будет выглядеть примерно так:

 ID | lowest time | 2nd lowest | 3rd lowest
----|-------------|------------|------------ 
 1  |  4.25       | 6.45       | 25.77  
 2  |  8.46       | 10.46      | 12.43  
 3  |  9.43       | 16.49      | 17.49
 5  |  9.43       | 16.97      |   

Ответы [ 2 ]

5 голосов
/ 29 июня 2011
CREATE TABLE times  (ID int, theTime Decimal(5,2));

INSERT INTO times VALUES (1, 6.45),
(2, 12.43),  
(1, 4.52),
(4, 16.24),
(5, 9.43),
(2, 10.46),
(2, 8.46),
(3, 17.49),
(4, 20.46),
(3, 16.49),
(5, 16.97),
(3, 9.43),
(1, 25.77);


SELECT DISTINCT
    id,
    (SELECT thetime FROM times t2 WHERE t.iD = t2.id 
     order by thetime limit 1) lowesttime,
    (SELECT thetime FROM times t2 WHERE t.iD = t2.id 
     order by thetime limit 1,1) secondlowest,
    (SELECT thetime FROM times t2 WHERE t.iD = t2.id 
     order by thetime limit 2,1) thirdlowest
 FROM 
    times t
 ORDER BY
    lowesttime,
    secondlowest,
    thirdlowest
LIMIT 3   ; 



SELECT t1.id, 
       Min(t1.thetime) lowesttime, 
       Min(t2.thetime) secondlowest, 
       Min(t3.thetime) thirdlowest 
FROM   times t1 
       LEFT JOIN times t2 
         ON t1.id = t2.id 
            AND t1.thetime < t2.thetime 
       LEFT JOIN times t3 
         ON t2.id = t3.id 
            AND t2.thetime < t3.thetime 
GROUP  BY t1.id 
ORDER  BY lowesttime, 
          secondlowest, 
          thirdlowest 
LIMIT  3 ;

Я думаю, что второй будет быстрее, но я не совсем уверен,

Обратите внимание, что, как выглядело замечательно, если ID 1 выглядел следующим образом

ID| Time
--------
1 | 4.52
1 | 4.52
1 | 25.77

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

ID | lowesttime | secondlowest | thirdlowest
-------------------------------------------
1  | 4.52       | 25.77        | null
2  |8.46        | 10.46        | 12.43
3  |9.43        | 16.49        | 17.49
0 голосов
/ 29 июня 2011

Попробуй это. Это будет работать для первого значения связи. Если вам нужно больше, вам нужно будет добавить дополнительные левые объединения и продублировать вторую часть заказа.

Это работает в SQL Server:

SELECT r1.ID, MIN(r1.time)
FROM #r r1
LEFT JOIN #r r2 
    on r1.Time = r2.Time
    AND r1.ID <> r2.ID
GROUP BY r1.id
ORDER BY MIN(r1.Time), MIN(CASE WHEN r2.time IS NULL THEN r1.time ELSE NULL END)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...