如何将指定PostgreSQL SQL语句转换为Sequelize实现?
将PostgreSQL过滤统计SQL转换为Sequelize标准实现
原SQL核心逻辑:按user_id和user_name分组,统计amount字段在不同区间的记录数量,并计算总记录数,仅筛选user_id不为空且属于指定列表的记录。
以下是用Sequelize标准API实现的代码(假设已定义对应表的模型为AmountTable):
const { Op, Sequelize } = require('sequelize'); async function getAmountStats() { const result = await AmountTable.findAll({ attributes: [ 'user_id', 'user_name', [Sequelize.fn('count', Sequelize.literal("* FILTER (WHERE amount > 30)")), 'over30'], [Sequelize.fn('count', Sequelize.literal("* FILTER (WHERE amount <= 30 AND amount > 0)")), 'under30'], [Sequelize.fn('count', Sequelize.literal("* FILTER (WHERE amount >= '-14'::integer AND amount < 0)")), 'less14'], [Sequelize.fn('count', Sequelize.literal("* FILTER (WHERE amount < '-14'::integer)")), 'over14'], [Sequelize.literal(` count(*) FILTER (WHERE amount > 30) + count(*) FILTER (WHERE amount <= 30 AND amount > 0) + count(*) FILTER (WHERE amount >= '-14'::integer AND amount < 0) + count(*) FILTER (WHERE amount < '-14'::integer) `), 'totals'] ], where: { user_id: { [Op.not]: null, [Op.in]: ['111', '112'] } }, group: ['user_id', 'user_name'], // 原SQL的DISTINCT可省略,GROUP BY已确保每组唯一 // distinct: true }); return result; }
关键细节说明:
- FILTER子句处理:Sequelize原生未直接支持PostgreSQL的
FILTER语法,通过Sequelize.literal()嵌入原生SQL片段实现对应逻辑。 - ANY数组匹配:原SQL的
user_id = any(array['111','112'])等价于Sequelize的[Op.in]操作符,写法更简洁且符合框架标准。 - 分组与去重:由于已按
user_id和user_name分组,原SQL中的DISTINCT可省略,分组结果本身已保证唯一性。 - 字段别名:通过数组形式在
attributes中定义字段别名,确保返回结果的键名与原SQL一致。
内容的提问来源于stack exchange,提问作者Joe Olu
相关产品推荐
相关产品推荐

