Лучшие значения в запросе по группе

Я знаю, как получить высшие значения, но у меня проблемы с чем-то очень простым.

У меня есть студенческий стол. В нем есть:

  • название
  • количество переворотов
  • оценка

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


person L Komita    schedule 19.01.2010    source источник
comment
Какую базу данных (включая версию) вы используете? А что вы пробовали?   -  person OMG Ponies    schedule 19.01.2010
comment
требуется больше информации. с помощью баз данных? какие языки/платформы и т.д...   -  person ghostdog74    schedule 19.01.2010


Ответы (2)


Использование MySQL:


MySQL не имеет функции ранжирования, но позволяет создавать и обновлять переменные:

SELECT x.grade,
       x.name,
       x.numberoflaps
  FROM (SELECT s.grade,
               s.name,
               s.numberoflaps,
               CASE 
                 WHEN @grade != s.grade THEN @rownum := 1 
                 ELSE @rownum := @rownum + 1
               END AS rank,
               @grade := s.grade
          FROM STUDENTS s,
               (SELECT @rownum := 0, @grade := NULL) r
      ORDER BY s.grade, s.numberoflaps DESC) x
 WHERE x.rank <= 2
ORDER BY x.grade, x.rank

ORDER BY в подзапросе важен, иначе ранжирование не будет выполнено должным образом.

Использование Oracle 9i+/SQL Server 2005+:


Использование КТЭ:

WITH laps AS (
  SELECT s.grade, 
         s.name, 
         s.numberoflaps,
         ROW_NUMBER() OVER (PARTITION BY grade ORDER BY numberoflaps DESC) AS rank
    FROM STUDENTS s)
  SELECT l.grade, 
         l.name, 
         l.numberoflaps
    FROM laps l
   WHERE l.rank <= 2
ORDER BY l.grade, l.numberoflaps DESC

Эквивалент без CTE:

  SELECT l.grade, 
         l.name, 
         l.numberoflaps
    FROM (SELECT s.grade, 
                 s.name, 
                 s.numberoflaps,
                 ROW_NUMBER() OVER (PARTITION BY grade ORDER BY numberoflaps DESC) AS rank
            FROM STUDENTS s) l
   WHERE l.rank <= 2
ORDER BY l.grade, l.numberoflaps DESC

Предостережение:

В Oracle 9i появилась функциональность ранжирования; для SQL Server это был 2005 год.

person OMG Ponies    schedule 19.01.2010

Версия SQL Server 2005+ будет выглядеть так:

;WITH Laps_CTE AS
(
    SELECT
        grade, name, numberoflaps,
        ROW_NUMBER() OVER (
            PARTITION BY grade
            ORDER BY numberoflaps DESC
        ) AS RowNum
    FROM students
)
SELECT grade, name, numberoflaps
FROM Laps_CTE
WHERE RowNum <= 2

Если это не ваш диалект, пожалуйста, сообщите нам, что это такое.

person Aaronaught    schedule 19.01.2010
comment
Я думаю, вы должны иметь WHERE RowNum ‹ 3, чтобы вернуть 2 верхние строки. - person Martin Booth; 19.01.2010
comment
Извините, я так долго писал этот комментарий. Ааронот уже исправил его! - person Martin Booth; 19.01.2010
comment
@Martin Booth: Здесь нужно быть быстрым :) - person OMG Ponies; 19.01.2010