Knex查询问题:按店主分组计算餐厅平均评分
正确的Knex关联查询写法:按店主分组计算餐厅平均评分
正确查询代码
const ownerAvgRatings = await knex('owners') // 关联餐厅表,匹配外键关系 .join('restaurants', 'owners.id', '=', 'restaurants.owner_id') // 选择店主名称,计算平均评分并指定别名 .select('owners.owner_name') .avg('restaurants.rating as avg') // 按店主主键+名称分组(主键避免重名店主被错误合并) .groupBy('owners.id', 'owners.owner_name') // 按店主名称升序排序 .orderBy('owners.owner_name', 'asc');
关键说明
- 关联方式:使用
join(内连接)仅返回拥有餐厅的店主;如果需要包含无餐厅的店主(此时avg为null),替换为leftJoin - 分组逻辑:必须同时按
owners.id和owners.owner_name分组——仅按名称分组会导致重名店主的评分被错误合并,主键是唯一标识,能保证分组准确性 - 字段别名:用
as avg将平均评分结果映射到预期的字段名 - 排序规则:明确指定
orderBy的字段和排序方向(asc升序,desc降序)
常见错误排查
如果之前的代码无法得到正确结果,大概率是以下原因:
- 分组时仅使用了
owner_name,未包含owners.id,导致重名数据合并错误 - 关联表的外键条件写错(比如误将
owners.id和restaurants.id关联) - 平均评分的字段未指定表前缀(比如直接写
avg(rating),当两张表有同名字段时会出错)
预期结果示例
[ { owner_name: 'Anna', avg: 4.2 }, { owner_name: 'Ben', avg: 3.9 }, { owner_name: 'Charlie', avg: 4.7 } ]
内容的提问来源于stack exchange,提问作者Logan Aaron
相关产品推荐
相关产品推荐

