在Sequelize Postgres中使用HAVING过滤嵌套模型求和结果
问题分析与解决方案
首先,咱们来拆解下你遇到的问题根源:你的group选项里包含了"items.id",这会让查询按每个捐赠子项单独分组,而不是按捐赠记录整体聚合计算总和。
举个实际例子:捐赠ID1有两个金额为2500的子项,当你按donations.id和items.id分组时,会生成两个独立的分组,每个分组的SUM结果都是2500——这两个值都小于捐赠金额5000,所以这条记录会被错误地返回。而捐赠ID2只有一个子项,分组后的SUM等于捐赠金额7500,所以被正确排除。
修正后的Sequelize代码
你需要调整两个核心点:
- 移除
group里的"items.id",只按捐赠记录的ID分组,这样才能计算该捐赠下所有符合条件的子项总和。 - 确保
having子句里的字段引用和Sequelize生成的SQL格式一致(注意引号的使用)。
修正后的代码如下:
Models.donations.findAndCountAll({ where: { status: 'OK' }, include: { model: Models.donation_items, as: 'items', duplicating: false, // 若需要包含无任何子项的捐赠记录,添加此行 // required: false }, group: ['"donations"."id"'], // 仅按捐赠ID分组,实现整体聚合 having: sequelize.literal(` COALESCE(SUM(CASE WHEN "items"."includeInTotals" = false THEN "items"."amount" ELSE 0 END), 0) < "donations"."amount" `) });
补充说明
COALESCE用来处理没有子项的捐赠记录,确保总和默认取0,避免SUM返回NULL导致的判断逻辑出错。- 如果业务需要保留无任何子项的捐赠记录,记得在
include配置里添加required: false(否则无关联子项的捐赠会被自动过滤)。 - 字段引用的引号要和Sequelize的自动生成规则匹配,避免出现字段找不到的报错。
内容的提问来源于stack exchange,提问作者Tom Maitland
相关产品推荐
相关产品推荐

