Группа MySQL с наивысшим номером N каждого типа
У меня есть таблица вроде этого:
Rank Letter
1 A
2 A
3 B
4 A
5 C
6 A
7 C
8 C
9 B
10 C
И мне нужна верхняя 2 каждой буквы, упорядоченная по возрастанию:
Rank Letter
1 A
2 A
3 B
5 C
7 C
9 B
Как мне это сделать? Это довольно просто, чтобы получить только первое 1, используя GROUP BY, но я не могу заставить его работать для нескольких записей.
Ответы
Ответ 1
select distinct rank, letter
from table1 t2
where rank in
(select top 2 rank
from table1 t2
where t2.letter = t1.letter
order by rank)
order by letter, rank
EDIT: (моя первая попытка не будет работать на MySql (комментарий Quassnoi), я модифицировал ее для работы на сервере sql например)
вторая попытка:
select t.letter, t.rank
from table1 t
join (
select t1.letter, min(t1.rank) m
from table1 t1
join (select t0.letter, min(t0.rank) m, count(1) c
from table1 t0 group by t0.letter) t2
on t1.letter = t2.letter and ((t2.c = 1) or (t2.c > 1 and t1.rank > m))
group by t1.letter) t3
on t.letter = t3.letter and t.rank <= t3.m
Ответ 2
SELECT mo.Letter, md.Rank
FROM (
SELECT DISTINCT letter
FROM mytable
) mo
JOIN mytable md
ON md.Letter >= mo.Letter
AND md.Letter <= mo.Letter
AND Rank <=
COALESCE
(
(
SELECT Rank
FROM mytable mi
WHERE mi.letter = mo.letter
ORDER BY
Rank
LIMIT 1, 1
),
0xFFFFFFFF
)
Вам нужно иметь составной индекс на (Letter, Rank)
(в этом порядке)
Обратите внимание на эту конструкцию:
md.Letter >= mo.Letter
AND md.Letter <= mo.Letter
вместо простого md.Letter = mo.Letter
Он повышает эффективность Range checked for each record
.
Смотрите эту статью в своем блоге:
для более подробной информации об этом.