按组获取数据库中的顶部(N),其中n是从sqlite

时间:2016-03-23 19:46:21

标签: sql sqlite greatest-n-per-group

我希望解决"选择top(N)by group"的变体。问题,但我的问题是必须在数据库中查找N.我有办法做到这一点,但我希望找到一个更清晰的方法。

如果有帮助,我使用的是sqlite3。

我正在设计一门课程,并有一个表格,用于指定要存储在表格gradeSyllabus中的权重:

title       weight      dropLowest
----------  ----------  ----------
Homework    0.6         0         
Test        0.4         1

即。家庭作业占整个等级的60%而没有掉落,而考试占成绩的40%,而考试成绩最低。

以下是来自table gradeGrades的一些假学生数据:

studentId   assess_title  assess_num  score     
----------  ------------  ----------  ----------
john345     Homework      1           75.0      
john345     Homework      2           85.0      
john345     Homework      3           64.0      
john345     Test          1           75.0      
john345     Test          2           85.0      
john345     Test          3           64.0      
mary111     Test          1           78.0      
mary111     Test          2           72.0      
mary111     Test          3           84.0      
mary111     Homework      1           90.0      
mary111     Homework      2           92.0      
mary111     Homework      3           88.0

我可以很容易地找到每个学生的平均分数:

SELECT GG.studentId, assess_title, avg(score) as overall, weight
   FROM gradeGrades GG INNER JOIN gradeSyllabus GS
   ON (assess_title = title)
   GROUP BY GG.studentId, assess_title;

这给出了以下结果:

studentId   assess_title  overall           weight    
----------  ------------  ----------------  ----------
john345     Homework      74.6666666666667  0.6       <-- correct
john345     Test          74.6666666666667  0.4       
mary111     Homework      90.0              0.6       <-- correct
mary111     Test          78.0              0.4 

测试需要降低最低测试。一般来说,我不能 使用min(因为我们可能会改变教学大纲以降低最低分 2次测试)。这是一个解决此问题的查询:

SELECT studentId, assess_title, sum(score) / count(*) as overall
   FROM gradegrades G1
        WHERE (select count(*) from gradegrades as G2
                   WHERE G1.studentid = G2.studentId AND
                         G1.assess_title = G2.assess_title AND
                         G2.score <= G1.score) -- select lowest
                         > (SELECT dropLowest FROM gradeSyllabus
                            WHERE gradeSyllabus.title = G1.assess_title)
   GROUP BY studentId, assess_title;

这会产生:

studentId   assess_title  overall         
----------  ------------  ----------------
john345     Homework      74.6666666666667  
john345     Test          80.0            
mary111     Homework      90.0            
mary111     Test          81.0  

其中所有整列都正确。

我的问题:

1)我可以从subselect中获得gradeSyllabus表中的权重吗?      或者我需要另一次加入吗?

2)是否有更好的(即更清晰的)生成此表的方法      第一名?效率会很好,但此刻我的      桌子很小(约30名学生)

3)查询存在(明显?)问题?

0 个答案:

没有答案