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

Sequelize关联查询:筛选匹配指定时间或无关联日历的服务

问题原因

当前查询使用required: false对Calendar表执行左连接,关联模型内配置的time:300过滤规则仅作用于关联的Calendar表查询,不会对主表Service的记录做过滤。
对于id=1的服务,其关联的Calendar记录time值为400,左连接时无法匹配time=300的条件,因此返回结果中它的Calendars字段为空数组,但Service主表行不会被剔除,最终导致不符合预期的记录被返回。

需求实际需要筛选满足任意以下条件的服务:

  • 关联Calendar记录中存在time等于目标值的条目
  • 无任何关联的Calendar记录

核心要排除的是「存在关联Calendar,但所有关联条目的time都不等于目标值」的服务,即测试数据中id=1的记录。

实现代码

推荐使用EXISTS子查询做过滤,逻辑清晰且不会破坏findAndCountAll的分页计数准确性,同时使用参数绑定避免SQL注入风险:

const { Op } = require('sequelize');
const targetTime = 300;

let result = await Service.findAndCountAll({
    where: {
        name: 'test',
        [Op.or]: [
            // 匹配存在目标时间关联日历的服务
            Sequelize.literal(`EXISTS (
                SELECT 1 FROM Calendars
                WHERE Calendars.serviceID = Service.id
                AND Calendars.time = :targetTime
            )`),
            // 匹配无任何关联日历的服务
            Sequelize.literal(`NOT EXISTS (
                SELECT 1 FROM Calendars
                WHERE Calendars.serviceID = Service.id
            )`)
        ]
    },
    include: [
        {
            model: Calendar,
            required: false,
            // 关联结果仅返回匹配目标时间的日历条目
            where: {
                time: targetTime
            }
        }
    ],
    replacements: {
        targetTime
    },
    offset: 0,
    limit: 10,
    distinct: true
});
结果校验

基于提供的测试数据,上述查询返回结果完全符合预期:

  • id=0:存在time=300的关联日历,命中第一条规则,正常返回
  • id=1:存在关联日历但time为400,不满足任何规则,被过滤
  • id=2:无任何关联日历,命中第二条规则,正常返回

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 15:48:36