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

如何用Sequelize筛选出最新订单在指定日期区间内的用户?

用Sequelize实现筛选最新订单在指定日期区间的用户

完全可以通过Sequelize实现这个需求,核心思路是先定位每个用户的最新订单,再判断该订单的createdAt是否落在指定日期范围内,最终筛选出符合条件的用户。以下提供几种可行的实现方案:

前提假设

已正确定义模型关联:

// User 模型关联
User.hasMany(Order, { foreignKey: 'userId' });
// Order 模型关联
Order.belongsTo(User, { foreignKey: 'userId' });

方案一:子查询筛选最新订单

通过子查询获取每个用户的最新订单ID,再关联订单表筛选日期区间,最终返回对应的用户:

const { Op } = require('sequelize');
const startDate = new Date('2023-01-01');
const endDate = new Date('2023-12-31');

const targetUsers = await User.findAll({
  include: [{
    model: Order,
    where: {
      // 筛选订单日期在指定区间内
      createdAt: {
        [Op.between]: [startDate, endDate]
      },
      // 子查询定位当前用户的最新订单ID
      id: {
        [Op.in]: sequelize.literal(`(
          SELECT id FROM orders 
          WHERE userId = User.id 
          ORDER BY createdAt DESC 
          LIMIT 1
        )`)
      }
    },
    required: true // 仅保留存在符合条件订单的用户(等价INNER JOIN)
  }]
});

方案二:聚合函数分组查询

先通过聚合函数获取每个用户的最新订单日期,筛选出日期在区间内的用户ID,再查询用户详情:

const { Op } = require('sequelize');
const startDate = new Date('2023-01-01');
const endDate = new Date('2023-12-31');

// 第一步:获取所有最新订单日期在区间内的用户ID
const userLatestOrderInfo = await Order.findAll({
  attributes: [
    'userId',
    [sequelize.fn('MAX', sequelize.col('createdAt')), 'latestCreatedAt']
  ],
  group: ['userId'],
  having: {
    latestCreatedAt: {
      [Op.between]: [startDate, endDate]
    }
  }
});

// 第二步:根据用户ID查询用户详情
const targetUserIds = userLatestOrderInfo.map(item => item.userId);
const targetUsers = await User.findAll({
  where: {
    id: { [Op.in]: targetUserIds }
  }
});

注意事项

  • 确保已导入Sequelize的操作符Op,否则无法使用[Op.between]、[Op.in]等条件
  • 若不需要返回订单数据,可在include的attributes中设置为空数组[]以优化查询性能
  • required: true会强制使用INNER JOIN,确保只返回存在符合条件订单的用户,若需保留无订单用户可改为false(但不符合本次需求场景)

内容的提问来源于stack exchange,提问作者Louis Grinwald

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 23:06:27