如何用Sequelize实现指定SQL的Distinct与Inner Join效果?
用Sequelize实现指定SQL的去重关联查询
嘿,我来帮你搞定这个Sequelize的去重问题!你的需求是关联三张表、按第三张表的日期倒序排序,并且避免重复的第三张表记录,和你给出的SQL逻辑完全对齐对吧?下面我给你几种靠谱的实现方式,你可以根据自己的数据库环境和代码习惯选:
方法一:使用GROUP BY实现去重(最简单直接)
如果你的数据库(比如PostgreSQL、MySQL 8.0+)允许在GROUP BY主键的情况下选取该表的所有字段,那这种方法最省心。核心思路是通过group选项按第三张表(Table3)的主键id分组,自动实现去重:
const { Table1, Table2, Table3 } = require('./models'); // 导入你的模型 const sequelize = require('./sequelize-instance'); // 导入你的Sequelize实例 const result = await Table3.findAll({ // 关联另外两张表,required: true 对应INNER JOIN include: [ { model: Table2, required: true, include: [ { model: Table1, required: true } ] } ], // 按Table3的id分组,确保每个Table3记录只出现一次 group: ['Table3.id'], // 按date倒序排序 order: [['date', 'DESC']], // 取前10条 limit: 10 });
这种方式生成的SQL和你原始的DISTINCT(c.id)逻辑几乎等价,因为分组后每个id只会保留一条记录,完全满足去重需求。
方法二:用子查询完全匹配原始SQL逻辑
如果你的数据库对GROUP BY的限制比较严格(比如开启了严格的ONLY_FULL_GROUP_BY模式且不允许非聚合字段),或者你想1:1复刻原始SQL的逻辑,那可以用子查询先获取去重后的Table3 id列表,再查询详细信息:
const result = await Table3.findAll({ where: { id: { // 直接把你的原始SQL作为子查询,获取符合条件的去重id [sequelize.Op.in]: sequelize.literal(` SELECT DISTINCT c.id FROM table1 a INNER JOIN table2 b ON b.id = a."table2Id" INNER JOIN table3 c ON c.id = b."table3Id" ORDER BY c.date DESC LIMIT 10 `) } }, // 关联另外两张表 include: [ { model: Table2, required: true, include: [ { model: Table1, required: true } ] } ], order: [['date', 'DESC']] });
这种方法的好处是完全遵循你原始SQL的逻辑,不会因为数据库差异出现意外问题,适合复杂场景。
方法三:在Attributes中指定DISTINCT
你也可以直接在attributes里使用Sequelize的fn方法来生成DISTINCT关键字,不过需要注意正确关联字段:
const result = await Table3.findAll({ attributes: [ [sequelize.fn('DISTINCT', sequelize.col('id')), 'id'], // 手动列出Table3的其他字段,比如:'name', 'date', ... 'name', 'date', 'otherField' ], include: [ { model: Table2, required: true, include: [ { model: Table1, required: true } ] } ], order: [['date', 'DESC']], limit: 10 });
这种方法需要手动列出Table3的所有字段,不如前两种方便,但如果只需要部分字段的话也可以用。
小提醒
确保你的模型关联已经正确配置:
Table1.belongsTo(Table2, { foreignKey: 'table2Id' })Table2.belongsTo(Table3, { foreignKey: 'table3Id' })
这样Sequelize才能自动生成正确的JOIN条件~
内容的提问来源于stack exchange,提问作者0xkvn
相关产品推荐
相关产品推荐

