如何使用Sequelize子查询删除SQL表中最旧的行?
问题描述
我想要删除表中指定用户的目标行(对应原生SQL逻辑为删除最新创建的行),原生SQL语句如下:
DELETE FROM `session` WHERE `id` IN ( SELECT `id` FROM `session` WHERE `userId` = :id ORDER BY `createdAt` DESC LIMIT 1 )
目前我用Sequelize是分两步实现:先查询出目标行的ID,再执行删除操作,代码如下:
const foundToken = await SessionModel.findOne({ attributes: ["id"], where: { userId: foundUser.id, }, order: [["createdAt", "DESC"]], }) if (foundToken) await SessionModel.destroy({ where: { id: foundToken.id, }, })
请问如何优化该实现,改用Sequelize子查询的方式完成此操作?
优化方案:Sequelize子查询实现
可以直接借助Sequelize的子查询能力,把查询和删除合并成一次数据库操作,具体实现有两种写法:
写法一:直接嵌套查询
const { Op } = require('sequelize'); await SessionModel.destroy({ where: { id: { [Op.in]: SessionModel.findAll({ attributes: ['id'], where: { userId: foundUser.id }, order: [['createdAt', 'DESC']], limit: 1, raw: true // 仅返回原始数据,减少不必要的实例包装 }) } } });
写法二:显式子查询构建(Sequelize 6+推荐)
这种写法逻辑更清晰,可读性更强:
const { Op } = require('sequelize'); // 先定义子查询 const targetIdSubQuery = SessionModel.select('id') .where({ userId: foundUser.id }) .order([['createdAt', 'DESC']]) .limit(1); // 执行删除 await SessionModel.destroy({ where: { id: { [Op.in]: targetIdSubQuery } } });
关键说明
- 两种写法都会生成和你提供的原生SQL逻辑完全一致的数据库语句,合并为单次请求,减少网络往返开销
raw: true选项可以让子查询直接返回纯数据数组,避免Sequelize创建模型实例,提升执行效率- 如果指定
userId没有对应的记录,子查询会返回空数组,此时destroy操作不会删除任何数据,和你原来的两步逻辑效果一致,无需额外判断
内容的提问来源于stack exchange,提问作者armada45
相关产品推荐
相关产品推荐

