我一直在编写SQL查询,这个函数类似于在一个月内返回学生的最新正式考试成绩,或者如果学生没有正式考试成绩,则返回最新的模拟考试成绩。
例如,这里有一张用来保存考试成绩的表格,列“mode”用于正式考试或模拟考试。
name class mode score exam_time
Alice Math mock 92 2019-03-21 10:00:00
Alice Math formal 88 2019-03-18 10:00:00
Alice Math formal 95 2019-03-07 10:00:00
Alice Science mock 89 2019-03-13 14:00:00
Bob Math mock 96 2019-03-21 10:00:00
Bob Math formal 90 2019-03-18 10:00:00
Bob Math formal 95 2019-03-07 10:00:00
Bob Science mock 98 2019-03-13 14:00:00
需要有如下查询结果:
Alice Math formal 88 2019-03-18 10:00:00
Alice Science mock 89 2019-03-13 14:00:00
Bob Math formal 90 2019-03-18 10:00:00
Bob Science mock 98 2019-03-13 14:00:00
对于数学,有正式考试和模拟考试,所以需要返回最新的正式考试,对于科学,只有模拟考试,所以返回模拟考试。
由于其他考虑,需要在一个SQL语句中实现它。
发布于 2019-04-19 12:25:16
这与Kaushik的方法略有不同。distinct on
是要走的路,但我会将逻辑写成:
select distinct on (name, class) t.*
from t
order by name, class, (mode = 'formal') desc, exam_time desc;
distinct on
为分组中的每组值返回一行(括号中的内容)。该行是由order by
确定的第一行。
发布于 2019-04-19 09:11:50
在Postgres,我更喜欢DISTINCT ON
来获得每个组的最高记录。它的性能稍好一些。
select DISTINCT ON (name,class) t.*
from t ORDER BY name,class,
case when mode = 'formal'
then 0 else 1 end,exam_time desc ;
发布于 2019-04-19 08:56:43
我们可以在这里使用row_number
:
select name, class, mode, score, exam_time
from
(
select t.*, row_number() over (partition by name, class
order by case when mode = 'formal' then 0 else 1 end,
date_trunc('month', exam_time) desc) rn
from your_table t
) t
where rn = 1;
上面与row_number
一起使用的分区逻辑将所有正式记录放在所有模拟记录之前。这意味着,只有在根本没有此类最新正式记录的情况下,才会返回模拟记录。
https://stackoverflow.com/questions/55759133
复制相似问题