我有一个问题,我无法处理......
我的PostgreSQL表看起来像这样:
id student grade class gradeDate
1 1 5 1 2017-03-03
2 1 5 1 2017-03-04
3 1 1 1 2017-03-05
4 1 5 1 2017-03-06
5 1 5 1 2017-03-07
6 1 5 1 2017-03-08
7 1 1 1 2017-03-09
8 2 5 2 2017-03-03
9 3 5 3 2017-03-03
所以我在不同的班级(1,2,3,4 ......)有不同的学生(1,2,3 ......),他们每天都获得成绩(gradeDate) - 它可能只有5或1 - 现在我想从这个数据库中选择每个学生排中最高等级5(排在行中我的意思是每天5级没有休息)所以在上面的表格中,用户1的最大数量将是3(第4,5行) ,6),对于用户2将是1并且对于用户3将是1。如果我将第3行中的成绩改为5,那么学生1的最大数量将是6你知道吗?
起初我想以某种方式使用SELECT查询,但首先 - 我不知道如何进行此查询,其次 - 当此表中将有数千或数百万行时,该查询的效率将非常非常低。我通常可以为学生1获取每一行并在Java中操作它。所以我问 - 我该如何解决这个问题?感谢您的时间和精力。
您需要识别相邻的组。一种简单的方法是行数的差异。要真正理解它,您需要运行子查询并盯着结果。您应该“看到”差异如何定义组。
select student, class, grade, count(*), min(gradeDate), max(gradeDate)
from (select t.*,
row_number() over (partition by student, class, grade order by gradeDate) as seqnum_scg,
row_number() over (partition by student, class order by gradeDate) as seqnum_sc
from t
) t
group by student, class, grade, (seqnum_sc - seqnum_scg);
为了获得最大值,您可以使用distinct on
。我将使用子查询:
select distinct on (student, class) scg.*
from (select student, class, grade, count(*) as cnt,
min(gradeDate), max(gradeDate), min_gradeDate, max_gradeDate
from (select t.*,
row_number() over (partition by student, class, grade order by gradeDate) as seqnum_scg,
row_number() over (partition by student, class order by gradeDate) as seqnum_sc
from t
) t
where grade = 5
group by student, class, grade, (seqnum_sc - seqnum_scg)
) scg
order by student, class, cnt desc;