如何用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
相关产品推荐
相关产品推荐

