如何用Sequelize按Region不同code分别统计去重company_id数量
问题描述
我有一段可正常运行的Sequelize查询代码:
const count = await models.CompanyProductionUnitNonCeased .count({ distinct: true, col: 'company_id', include: [{ required: true, model: models.ProductionUnitCore, as: "production_unit", include: [{ required: true, model: models.ProductionUnitAddress, as: 'production_unit_addresses', where: { is_current: true }, include: [{ required: true, model: models.AddressAddress, as: 'address', include: [{ required: true, model: models.GeograpicalAdministrativeAreas, as: 'geograpical_administrative_areas', include: [{ required: true, model: models.Region, as: 'region_code_region', where: {code: [1081, 1082]} }], }] }] }] }] })
这段代码会返回Region表中code为1081和1082的记录对应的去重company_id总数。现在Region表的code字段有5个不同取值,且是GeograpicalAdministrativeAreas表的主键。我需要针对每个code分别统计对应的数量,期望结果格式如下:
[{ 1081: 1001, 1082: 2002, 1083: 2222, 1084: 4344, 1085: 143434 }]
解决方案
要实现按每个Region code单独统计去重company_id数量,需要用findAll配合分组查询和聚合函数,再将结果转换为目标格式:
基础实现(仅统计有数据的code)
const regionCounts = await models.CompanyProductionUnitNonCeased.findAll({ attributes: [ 'region_code_region.code', // 统计去重后的company_id数量 [models.sequelize.fn('COUNT', models.sequelize.fn('DISTINCT', models.sequelize.col('company_id'))), 'count'] ], include: [{ required: true, model: models.ProductionUnitCore, as: "production_unit", include: [{ required: true, model: models.ProductionUnitAddress, as: 'production_unit_addresses', where: { is_current: true }, include: [{ required: true, model: models.AddressAddress, as: 'address', include: [{ required: true, model: models.GeograpicalAdministrativeAreas, as: 'geograpical_administrative_areas', include: [{ required: true, model: models.Region, as: 'region_code_region' // 移除原where条件,统计所有region code }], }] }] }] }], // 按region code分组 group: ['region_code_region.code'], // 返回原始数据结构,方便后续转换 raw: true }); // 转换为期望的键值对格式 const result = [regionCounts.reduce((acc, item) => { acc[item.code] = parseInt(item.count); return acc; }, {})];
强制包含所有code(无数据时显示0)
如果需要确保所有5个region code都出现在结果中(即使对应计数为0),可以手动补充缺失的code:
const allRegionCodes = [1081, 1082, 1083, 1084, 1085]; // 基于基础查询结果生成完整统计 const result = [allRegionCodes.reduce((acc, code) => { const matched = regionCounts.find(item => item.code === code); acc[code] = matched ? parseInt(matched.count) : 0; return acc; }, {})];
关键说明
- 用
findAll替代count:count方法无法直接实现分组统计,findAll配合group和聚合函数更灵活 - 聚合函数
COUNT(DISTINCT company_id):确保每个company_id在同一region下只被统计一次 - 移除Region表的
where条件:这样会覆盖所有存在的region code,而非仅指定的两个 raw: true:简化返回的数据结构,减少后续转换的复杂度
内容的提问来源于stack exchange,提问作者Vyacheslav Tarshevskiy
相关产品推荐
相关产品推荐

