Laravel用group by多表关联统计城市与品牌数量结果相同如何修复
问题原因
你遇到的统计值一致问题是同时关联brands和cities两个表产生笛卡尔积导致的:同一个州下的每一条城市记录会和每一条同州的品牌记录交叉拼接生成新行,最终count统计的都是交叉拼接后的总行数,所以两个统计结果完全相同。
修复方案
方案1:COUNT统计加DISTINCT去重
适合小数据量场景,修改成本最低,只需给要统计的id字段加DISTINCT去重即可:
DB::table('states') ->join('brands', 'brands.state_id', '=', 'states.state_id') ->join('cities', 'cities.state_id', '=', 'states.state_id') ->select( 'state_name', DB::raw("COUNT(DISTINCT cities.city_id) as cities"), DB::raw("COUNT(DISTINCT brands.brand_id) as brands") ) ->groupBy('state_name') ->get();
方案2:子查询单独统计指标(性能更优)
适合生产环境大数据量场景,避免生成笛卡尔积,查询效率更高:
$citiesCount = DB::table('cities') ->selectRaw('COUNT(*)') ->whereColumn('cities.state_id', 'states.state_id'); $brandsCount = DB::table('brands') ->selectRaw('COUNT(*)') ->whereColumn('brands.state_id', 'states.state_id'); DB::table('states') ->select('state_name') ->selectSub($citiesCount, 'cities') ->selectSub($brandsCount, 'brands') ->get();
提示:如果需要保留没有下属城市/没有下属品牌的州记录,方案1可将
join替换为leftJoin,方案2本身就支持输出所有州的统计结果。
内容的提问来源于stack exchange,提问作者Abdullah Al Mamun
相关产品推荐
相关产品推荐

