如何在Sequelize函数中添加where条件实现多规则多字段求和查询
最优实现方案
直接用SUM聚合嵌套CASE WHEN条件即可,只需要单次数据库查询就能拿到所有分组的求和结果,比你当前在用的两种方案性能好很多:多查询并行会有额外的数据库连接IO开销,拉全表到Node端计算会浪费大量带宽和内存,数据量大的时候性能差距会非常明显。
基础实现示例
对应你需求的代码写法如下:
model.findAll({ attributes: [ // 满足condition1的求和统计 [ sequelize.fn('SUM', sequelize.literal(`CASE WHEN 这里写你的condition1条件 THEN columnA ELSE 0 END`) ), 'sumA1' ], [ sequelize.fn('SUM', sequelize.literal(`CASE WHEN 这里写你的condition1条件 THEN columnB ELSE 0 END`) ), 'sumB1' ], // 满足condition2的求和统计 [ sequelize.fn('SUM', sequelize.literal(`CASE WHEN 这里写你的condition2条件 THEN columnA ELSE 0 END`) ), 'sumA2' ], [ sequelize.fn('SUM', sequelize.literal(`CASE WHEN 这里写你的condition2条件 THEN columnB ELSE 0 END`) ), 'sumB2' ] ], // 可以加所有统计都通用的全局where条件,减少数据库扫描行数 where: { // 比如所有统计都限定时间范围:create_time >= '2024-01-01' }, raw: true // 不需要实例对象的话加这个参数,直接返回纯JSON结果 })
逻辑说明:聚合计算时只有满足对应条件的行才会把字段值计入求和,不满足的行取0不影响最终结果,和你分开多次查询的结果完全一致。
多条件批量生成优化
如果需要统计的条件组很多,可以封装工具函数批量生成attributes,避免重复代码:
// 预先定义所有需要统计的条件组 const sumRules = [ { suffix: '1', condition: 'status = 1 AND type = "order"' }, { suffix: '2', condition: 'status = 2 AND type = "refund"' } // 更多条件直接追加即可 ] // 批量生成聚合配置 const attributes = sumRules.flatMap(rule => [ [ sequelize.fn('SUM', sequelize.literal(`CASE WHEN ${rule.condition} THEN columnA ELSE 0 END`)), `sumA${rule.suffix}` ], [ sequelize.fn('SUM', sequelize.literal(`CASE WHEN ${rule.condition} THEN columnB ELSE 0 END`)), `sumB${rule.suffix}` ] ]) // 执行查询 const result = await model.findAll({ attributes, raw: true })
安全注意事项
如果条件里包含用户传入的动态参数,不要直接拼接SQL字符串,要使用Sequelize的参数绑定能力避免SQL注入风险,示例如下:
const attributes = [ [ sequelize.fn('SUM', sequelize.literal(`CASE WHEN user_id = ? THEN columnA ELSE 0 END`)), 'sumAUser' ] ] const result = await model.findAll({ attributes, replacements: [currentUserId], // 动态参数放在这里自动转义 raw: true })
内容的提问来源于stack exchange,提问作者Alem Leon
相关产品推荐
相关产品推荐

