MySQL分组方式,每种类型前N个

MySQL分组方式,每种类型前N个,mysql,group-by,ranking,Mysql,Group By,Ranking,我有一张这样的桌子: 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

我有一张这样的桌子:

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 我该怎么做?使用GROUPBY只获得前1名是相当简单的,但我似乎无法让它用于多个条目

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
                )
而不仅仅是md.字母=mo.字母

它强制检查每个记录的范围,这样更有效

请参见我的博客中的这篇文章:

有关这方面的更多详细信息

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
编辑:我的第一次尝试在MySql上不起作用。例如,我修改了它以在sql server上工作

第二次尝试:

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

我得到一个错误1242-子查询返回超过1行,因为最后一个子查询的限制是2,你知道为什么吗?这是一个旧答案,但我发现它很有用。然而,我确实发现它并不像预期的那样有效。例如,如果一封信的实例少于2个,它将不会返回任何实例。您可以添加如下内容:或者从mytable mi中选择COUNT*,其中mi.letter=mo.letter@Quassnoi非常好-我更喜欢您的版本,谢谢:对不起,我更多地使用sql server。现在我必须为mysql找到另一个不同于您的解决方案;
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