Топ х строк и сгруппировать (снова) - PullRequest
3 голосов
/ 05 мая 2010

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

Пример таблицы:

id | title | group_id | votes

Я бы хотел получить первые 3 строки с голосами из таблицы для каждой группы.

Я ожидаю этого результата:

91 | hello1 | 1 | 10 
28 | hello2 | 1 | 9
73 | hello3 | 1 | 8 
84 | hello4 | 2 | 456
58 | hello5 | 2 | 11 
56 | hello6 | 2 | 0 
17 | hello7 | 3 | 50
78 | hello8 | 3 | 9 
99 | hello9 | 3 | 1 

Мне нравятся сложные запросы и примеры, но они действительно не помогли.

1 Ответ

3 голосов
/ 05 мая 2010

Вы можете сделать это с помощью переменных:

SELECT
   id,
   title,
   group_id,
   votes
FROM (
    SELECT
        id,
        title,
        group_id,
        votes,
        @rn := CASE WHEN @prev = group_id THEN @rn + 1 ELSE 1 END AS rn,
        @prev := group_id
    FROM table1, (SELECT @prev := -1, @rn := 0) AS vars
    ORDER BY group_id DESC, votes DESC
) T1
WHERE rn <= 3
ORDER BY group_id, votes DESC

Это в основном аналогично следующему запросу в базах данных, которые поддерживают ROW_NUMBER:

SELECT
   id,
   title,
   group_id,
   votes
FROM (
     SELECT
        id,
        title,
        group_id,
        votes,
        ROW_NUMBER() OVER (PARTITION BY group_id ORDER BY votes DESC) AS rn
     FROM student
) T1
WHERE rn <= 3
ORDER BY group_id, votes DESC

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...