使用Sequelize findAndCountAll带literal计数与having子句报错求助
解决Sequelize findAndCountAll中HAVING子句无法识别别名的问题
你遇到的错误根源是SQL执行顺序的限制:HAVING子句的执行逻辑早于SELECT子句的别名解析,因此直接使用banCount这个别名会被数据库判定为不存在的列。下面提供两种可行的解决方法:
方法一:在HAVING中重复计数表达式
直接将SELECT里的计数literal复制到HAVING条件中,让数据库能识别计算逻辑:
const users = await db.User.findAndCountAll({ attributes: { include: [ [ fn('(SELECT COUNT(*) FROM `Bans` WHERE `Bans`.`UserId` = `User`.`id` AND `Bans`.`active` = true)'), 'banCount', ], ], }, having: { // 重复SELECT中的计数表达式 [fn('(SELECT COUNT(*) FROM `Bans` WHERE `Bans`.`UserId` = `User`.`id` AND `Bans`.`active` = true)')]: 0 }, });
方法二:用子查询包装实现过滤
先查询出包含banCount的用户数据,再在外层过滤banCount=0的记录,同时完成计数统计:
const users = await db.User.findAndCountAll({ subQuery: false, attributes: { include: [ [ fn('(SELECT COUNT(*) FROM `Bans` WHERE `Bans`.`UserId` = `User`.`id` AND `Bans`.`active` = true)'), 'banCount', ], ], }, // 直接在WHERE中嵌入计数逻辑实现过滤 where: db.sequelize.literal('(SELECT COUNT(*) FROM `Bans` WHERE `Bans`.`UserId` = `User`.`id` AND `Bans`.`active` = true) = 0') });
补充说明
部分高版本数据库(如MySQL 8.0+)支持在HAVING中直接引用SELECT别名,但为了兼容低版本环境,上述两种方法是更稳妥的选择。
内容的提问来源于stack exchange,提问作者Travis Delly
相关产品推荐
相关产品推荐

