Laravel单查询实现同表分组多统计并关联用户表
一次查询搞定攻击/受害次数统计+用户名称关联
嘿,我明白你现在的需求——把原来四次分开的查询合并成一次,直接拿到包含用户名、攻击次数、受害次数的结果对吧?这完全可以通过子查询左连接来实现,我给你用Laravel Query Builder写好,直接就能用!
最终实现代码
$result = DB::table('Table2') // 左连接攻击次数统计子查询 ->leftJoin(DB::raw('( SELECT attacker AS userid, COUNT(*) AS attack_count FROM Table1 WHERE attacker <> 1 GROUP BY attacker ) AS attack_stats'), function($join) { $join->on('Table2.userid', '=', 'attack_stats.userid'); }) // 左连接受害次数统计子查询 ->leftJoin(DB::raw('( SELECT victim AS userid, COUNT(*) AS victim_count FROM Table1 WHERE victim <> 1 GROUP BY victim ) AS victim_stats'), function($join) { $join->on('Table2.userid', '=', 'victim_stats.userid'); }) // 选择字段,用COALESCE处理没有记录的情况(转成0) ->select([ 'Table2.name', DB::raw('COALESCE(attack_stats.attack_count, 0) AS attack_count'), DB::raw('COALESCE(victim_stats.victim_count, 0) AS victim_count') ]) ->get();
逻辑说明
- 子查询统计次数:先分别用两个子查询统计每个
userid的攻击次数和受害次数,过滤掉userid=1的记录(和你原来的查询逻辑保持一致)。 - 左连接用户表:把两个统计结果左连接到
Table2,这样即使某个用户没有攻击/受害记录,也能被查询到,不会被过滤掉。 - 处理空值:用
COALESCE函数把NULL(没有对应记录时的结果)转换成0,保证输出格式统一。
输出结果
执行后你会得到和期望完全一致的结果:
| name | attack_count | victim_count |
|---|---|---|
| John | 3 | 1 |
| Joe | 1 | 4 |
| Peter | 2 | 1 |
这样就不用再做四次查询然后手动合并结果了,一次数据库请求搞定所有事,效率更高也更简洁~
内容的提问来源于stack exchange,提问作者IndiFFer3nT
相关产品推荐
相关产品推荐

