如何使用 Sequelize.JS 选择具有 2 个唯一列的所有行?
Posted
技术标签:
【中文标题】如何使用 Sequelize.JS 选择具有 2 个唯一列的所有行?【英文标题】:How to select all rows with 2 unique columns with Sequelize.JS? 【发布时间】:2022-01-13 13:25:36 【问题描述】:我有一个名为 grade
的表,有 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 |
我想选择所有行,其中只有每个学生的每个科目的最后一个年级。基本上,我想选择所有具有唯一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
【问题讨论】:
我不知道如何在 Sequelize.JS 中编写,但在 postgres 中,您需要在 (student_id 和 subject_id ) 上按日期 DESC 顺序使用窗口函数和 【参考方案1】:你很接近。您按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 创建为
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 提到的窗口函数的使用。
DISTINCT ON
和 ROW_NUMBER
的一些有趣的基准测试
https://***.com/a/34715134/2956135
【讨论】:
谢谢@Emma!我尝试将id
添加到属性中并得到以下错误:SequelizeDatabaseError: column "grade.id" must appear in the GROUP BY clause or be used in an aggregate function
。有什么想法吗?
您可以在原始问题中添加您当前的findAll
函数吗?请保留原代码。
您的回答无效,我收到以下错误:SequelizeDatabaseError: column "grade.grade" must appear in the GROUP BY clause or be used in an aggregate function
。它仅在我删除 grade
属性时才有效。
我的错。我在sqlite
上进行测试,但在 postgres 中不允许使用此 SQL。我会更新的。
感谢@Emma 非常有帮助的回答!以上是关于如何使用 Sequelize.JS 选择具有 2 个唯一列的所有行?的主要内容,如果未能解决你的问题,请参考以下文章