SQLlite试图在获取另一个属性的最大值后获取该属性的最小值

SQLlite试图在获取另一个属性的最大值后获取该属性的最小值,sql,sqlite,Sql,Sqlite,我有ff模式: student: sid (string) course: cid (string) prerequisite: cid (string), precid (string) record: sid (string), cid (string), quarter (string), year (integer), grade(integer) 使用SQLlite: 对于每一个至少上过一堂课的学生,也就是说一个学生至少被输入记录表一次,我需要得到他们最近一个季度的GPA。我需要显示

我有ff模式:

student: sid (string)
course: cid (string)
prerequisite: cid (string), precid (string)
record: sid (string), cid (string), quarter (string), year (integer), grade(integer)
使用SQLlite: 对于每一个至少上过一堂课的学生,也就是说一个学生至少被输入记录表一次,我需要得到他们最近一个季度的GPA。我需要显示sid、季度、年度和年级gpa

在给定的日历年中有3个季度,观察季度的出现顺序可能会有所帮助,其字母顺序为“W”>“S”>“F”。这些分别代表冬天、春天、秋天。秋天是今年的最后一个季度

我的想法是,首先为每个参加过课程的学生计算最长学年,然后计算该学年的最小季度,最小季度得到该学年的最新季度,然后计算这些结果中的平均成绩

看来我只需要记录表。 为了获得他们最近一年的注册情况,我使用max函数:

select *, max(year)
from record
group by sid;
这成功地为我提供了每一个参加过课程的学生的最近一年

现在,当我尝试获取他们当年注册的最新季度时,我使用minquarter,然后我尝试使用avggrade获取他们最近一个季度的gpa,但结果最终得到他们参加的所有课程的平均值,并显示最小季度,而不考虑年份

select sid, quarter, year, avg(grade) as gpa
from (select sid, min(quarter) as quarter, year, avg(grade) as grade
    from (select *, max(year) as maxy
        from record
        group by sid)
    group by sid)
group by sid;
这给了我所有注册季度/年份的平均分数,也没有给我最近一个季度的分数

我可以使用的函数有group by、order、by、聚合函数min、max、avg、not exist/exist、in/not in


任何帮助都将不胜感激。谢谢大家!

您可以使用窗口函数RANK仅过滤最近一年/季度的行,然后进行聚合以获得平均等级:

SELECT sid, year, quarter, AVG(grade) gpa
FROM (
  SELECT *, RANK() OVER (PARTITION BY sid ORDER BY year DESC, quarter) rnk
  FROM record
)
WHERE rnk = 1
GROUP BY sid, year, quarter
没有窗口函数,具有相关子查询:

SELECT r1.sid, r1.year, r1.quarter, AVG(r1.grade) gpa
FROM record r1
WHERE (r1.year, r1.quarter) = (
  SELECT r2.year, r2.quarter
  FROM record r2
  WHERE r2.sid = r1.sid
  ORDER BY r2.year DESC, r2.quarter
  LIMIT 1
)
GROUP BY r1.sid, r1.year, r1.quarter
或不存在:


请参阅一个简化的示例。

是否仍可以在不使用秩的情况下执行此操作。比如说,像使用不存在函数一样,对于特定的季度,最近的季度意味着没有成功quarter@dante看我编辑的答案。这太棒了!谢谢
SELECT r1.sid, r1.year, r1.quarter, AVG(r1.grade) gpa
FROM record r1
WHERE NOT EXISTS (
  SELECT 1 FROM record r2
  WHERE r2.sid = r1.sid AND (r2.year > r1.year OR (r2.year = r1.year AND r2.quarter < r1.quarter))
)
GROUP BY r1.sid, r1.year, r1.quarter