如何使用特定值和特定用户/人(在行)计算数据?

问题描述 投票:1回答:1

我有一个问题,我无法处理......

我的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中操作它。所以我问 - 我该如何解决这个问题?感谢您的时间和精力。

java sql postgresql count
1个回答
1
投票

您需要识别相邻的组。一种简单的方法是行数的差异。要真正理解它,您需要运行子查询并盯着结果。您应该“看到”差异如何定义组。

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;
© www.soinside.com 2019 - 2024. All rights reserved.