从每个组sqlite中选择前n个记录

Smi*_*ith 5 sql sqlite greatest-n-per-group

我试图从数据库表结果中选择前2个记录,如下所示

SubjectId |  StudentId | Levelid | total
------------------------------------------
 1        |  1         |   1     | 89
 1        |  2         |   1     | 77
 1        |  3         |   1     | 61
 2        |  4         |   1     | 60
 2        |  5         |   1     | 55
 2        |  6         |   1     | 45
Run Code Online (Sandbox Code Playgroud)

我试过这个查询

SELECT rv.subjectid,
       rv.total,
       rv.Studentid,
       rv.levelid
  FROM ResultView rv
       LEFT JOIN ResultView rv2
              ON ( rv.subjectid = rv2.subjectid 
    AND
rv.total <= rv2.total ) 
 GROUP BY rv.subjectid,
          rv.total,
          rv.Studentid
HAVING COUNT( * ) <= 2
order by rv.subjectid desc  
Run Code Online (Sandbox Code Playgroud)

但是有些科目在哪里失踪,我甚至尝试了以下链接的建议

如何选择每组的前N行?

但是对于每个主观,我得到的更多

我究竟做错了什么?

And*_*mar 8

您可以使用相关子查询:

select  *
from    ResultView rv1
where   SubjectId || '-' || StudentId || '-' || LevelId in
        (
        select  SubjectId || '-' || StudentId || '-' || LevelId
        from    ResultView rv2
        where   SubjectID = rv1.SubjectID
        order by
                total desc
        limit   2
        )
Run Code Online (Sandbox Code Playgroud)

此查询通过连接三列来构造单列主键.如果你有一个真正的主键(如ResultViewID),你可以替换它SubjectId || '-' || StudentId || '-' || LevelId.

SQL Fiddle的例子.


小智 8

我希望我能正确理解你的问题。让我知道这是否正确:

我重新创建了你的表:

CREATE TABLE stack (
       SubjectId INTEGER(10),
       StudentId INTEGER(10),
       Levelid INTEGER(10),
       total INTEGER(10)
       )
;
Run Code Online (Sandbox Code Playgroud)

插入的值

INSERT INTO stack VALUES
       (1,1,1,89),
       (1,2,1,77),
       (1,3,1,61),
       (2,4,1,60),
       (2,5,1,55),
       (2,6,1,45)
;
Run Code Online (Sandbox Code Playgroud)

如果您尝试按 Levelid 获取顶级组(按总字段排序,假设 StudentID 作为主键):

SELECT * 
FROM stack AS a
WHERE a.StudentID IN (
      SELECT b.StudentID
      FROM stack AS b
      WHERE a.levelid = b.levelid
      ORDER BY b.total DESC
      LIMIT 2
      )
;
Run Code Online (Sandbox Code Playgroud)

产生这样的结果:

SubjectId | StudentId | Levelid | total
1         | 1         | 1       | 89
1         | 2         | 1       | 77
Run Code Online (Sandbox Code Playgroud)

SubjectId 前 2 名的示例,按总数排序:

SELECT * 
FROM stack AS a
WHERE a.StudentID IN (
      SELECT b.StudentID
      FROM stack AS b
      WHERE a.subjectID = b.subjectID
      ORDER BY b.total DESC
      LIMIT 2
      )
;
Run Code Online (Sandbox Code Playgroud)

结果:

SubjectId | StudentId | Levelid | total
1         | 1         | 1       | 89
1         | 2         | 1       | 77
2         | 4         | 1       | 60
2         | 5         | 1       | 55
Run Code Online (Sandbox Code Playgroud)

我希望这就是你要找的答案。