You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 05:26:13