如何 select 具有 2 个唯一列的所有行 Sequelize.JS?
How to select all rows with 2 unique columns with Sequelize.JS?
我有一个名为 grade
的 table,有 4 列:student_id
、subject_id
、grade
和 date
。
student_id
subject_id
grade
date
Jenny
math
90
2021-12-08
Susan
math
60
2021-12-08
Jenny
math
80
2021-12-07
Susan
math
50
2021-12-07
Jenny
science
80
2021-12-08
Susan
science
90
2021-12-08
Jenny
science
76
2021-12-06
Susan
science
85
2021-12-06
我想 select 所有行只包含每个学生每个科目的最后成绩。基本上,我想 select 所有具有唯一 student_id
、subject_id
的行,如下所示:
student_id
subject_id
grade
date
Jenny
math
90
2021-12-08
Susan
math
60
2021-12-08
Jenny
science
80
2021-12-08
Susan
science
90
2021-12-08
这是我尝试过的:
await Grade.findAll({
attributes: ['student_id', 'subject_id', 'grade', 'date'],
raw: true,
group: ['student_id', 'subject_id']
})
但是,我收到以下错误:
SequelizeDatabaseError: column "grade.grade" must appear in the GROUP BY clause or be used in an aggregate function
你很接近。您正在按 student_id
和 subject_id
分组,您只需要 MAX('date')
.
await Grade.findAll({
attributes: ['student_id', 'subject_id', 'grade', [Sequelize.fn('max', Sequelize.col('date')), 'date']],
raw: true,
group: ['student_id', 'subject_id']
})
属性中的数组可以执行给定名称的功能和别名[function, alias]
。
例如:
[Sequelize.fn('max', Sequelize.col('date')), 'new_name']]
属性中的此语法创建 SQL as
MAX(`date`) as `new_name`
============================================= ===========
更新:
以上查询在 Postgres 中不起作用。
参考:https://dba.stackexchange.com/a/194352
要在 Postgres 中实现相同的查询,一种替代解决方案是使用 DISTINCT ON
.
await Grade.findAll({
attributes: [Sequelize.literal('DISTINCT ON ("student_id", "subject_id") *'),
'id', 'student_id', 'subject_id', 'date', 'grade'],
order: ['student_id', 'subject_id', ['date', 'DESC']]
})
更多DISTINCT ON
查询,请查看https://zaiste.net/posts/postgresql-distinct-on/
本文还涉及了@sia提到的window函数的使用。
DISTINCT ON
和 ROW_NUMBER
的一些有趣的基准测试
我有一个名为 grade
的 table,有 4 列:student_id
、subject_id
、grade
和 date
。
student_id | subject_id | grade | date |
---|---|---|---|
Jenny | math | 90 | 2021-12-08 |
Susan | math | 60 | 2021-12-08 |
Jenny | math | 80 | 2021-12-07 |
Susan | math | 50 | 2021-12-07 |
Jenny | science | 80 | 2021-12-08 |
Susan | science | 90 | 2021-12-08 |
Jenny | science | 76 | 2021-12-06 |
Susan | science | 85 | 2021-12-06 |
我想 select 所有行只包含每个学生每个科目的最后成绩。基本上,我想 select 所有具有唯一 student_id
、subject_id
的行,如下所示:
student_id | subject_id | grade | date |
---|---|---|---|
Jenny | math | 90 | 2021-12-08 |
Susan | math | 60 | 2021-12-08 |
Jenny | science | 80 | 2021-12-08 |
Susan | science | 90 | 2021-12-08 |
这是我尝试过的:
await Grade.findAll({
attributes: ['student_id', 'subject_id', 'grade', 'date'],
raw: true,
group: ['student_id', 'subject_id']
})
但是,我收到以下错误:
SequelizeDatabaseError: column "grade.grade" must appear in the GROUP BY clause or be used in an aggregate function
你很接近。您正在按 student_id
和 subject_id
分组,您只需要 MAX('date')
.
await Grade.findAll({
attributes: ['student_id', 'subject_id', 'grade', [Sequelize.fn('max', Sequelize.col('date')), 'date']],
raw: true,
group: ['student_id', 'subject_id']
})
属性中的数组可以执行给定名称的功能和别名[function, alias]
。
例如:
[Sequelize.fn('max', Sequelize.col('date')), 'new_name']]
属性中的此语法创建 SQL as
MAX(`date`) as `new_name`
============================================= ===========
更新:
以上查询在 Postgres 中不起作用。
参考:https://dba.stackexchange.com/a/194352
要在 Postgres 中实现相同的查询,一种替代解决方案是使用 DISTINCT ON
.
await Grade.findAll({
attributes: [Sequelize.literal('DISTINCT ON ("student_id", "subject_id") *'),
'id', 'student_id', 'subject_id', 'date', 'grade'],
order: ['student_id', 'subject_id', ['date', 'DESC']]
})
更多DISTINCT ON
查询,请查看https://zaiste.net/posts/postgresql-distinct-on/
本文还涉及了@sia提到的window函数的使用。
DISTINCT ON
和 ROW_NUMBER
的一些有趣的基准测试