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

Sequelize中$and连接两个函数查询失效问题求助

解决Sequelize中日期函数条件的AND拼接问题

我来帮你搞定这个查询问题~你遇到的情况是因为旧版的$and运算符在新版本Sequelize里可能存在兼容性问题,而且写法上也可以更规范。

问题根源

你用的$and是Sequelize的旧版语法,从v4版本开始官方就推荐使用sequelize.Op.and来明确表示AND关系。另外,你原来的写法里,$and数组中的两个条件只有后者生效,大概率是因为旧语法解析时的优先级问题。

正确写法1:使用Op.and规范拼接条件

直接把日期函数条件放到Op.and数组中,和其他顶级条件(state、userId)共存即可,Sequelize会自动将所有条件用AND连接:

models.trees.findOne({ 
  where: { 
    state: { [sequelize.Op.eq]: "Publish" }, 
    userId: { [sequelize.Op.eq]: id },
    // 使用新版Op.and替代$and
    [sequelize.Op.and]: [
      sequelize.where(sequelize.fn("MONTH", sequelize.fn("CURRENT_DATE")), sequelize.fn("MONTH", sequelize.col("createdAt"))),
      sequelize.where(sequelize.fn("YEAR", sequelize.fn("CURRENT_DATE")), sequelize.fn("YEAR", sequelize.col("createdAt")))
    ]
  }, 
  attributes: [ [sequelize.fn("COUNT", sequelize.col("userId")), "count_trees"] ] 
});

更简洁的写法:用sequelize.literal直接写SQL片段

如果觉得嵌套fn太繁琐,也可以用literal直接编写SQL片段,可读性更强:

models.trees.findOne({ 
  where: { 
    state: "Publish", // eq运算符可以省略,默认就是等于
    userId: id,
    [sequelize.Op.and]: [
      sequelize.literal('MONTH(CURRENT_DATE) = MONTH(`createdAt`)'),
      sequelize.literal('YEAR(CURRENT_DATE) = YEAR(`createdAt`)')
    ]
  }, 
  attributes: [ [sequelize.fn("COUNT", sequelize.col("userId")), "count_trees"] ] 
});

额外建议:用count方法替代findOne统计数量

你这里的需求是统计符合条件的记录数,其实用count方法更直接,不需要手动指定attributes:

models.trees.count({ 
  where: { 
    state: "Publish",
    userId: id,
    [sequelize.Op.and]: [
      sequelize.where(sequelize.fn("MONTH", sequelize.fn("CURRENT_DATE")), sequelize.fn("MONTH", sequelize.col("createdAt"))),
      sequelize.where(sequelize.fn("YEAR", sequelize.fn("CURRENT_DATE")), sequelize.fn("YEAR", sequelize.col("createdAt")))
    ]
  }
}).then(count => {
  // 这里的count就是你想要的count_trees值
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 07:46:16