关联用户与已填表单表,按条件实现聚合统计(DB::Raw咨询)
当然可以用
DB::Raw实现这个需求! 这种带条件的聚合统计场景,用DB::Raw来直接编写原生聚合逻辑是非常合适的。我给你分两种常见场景来给出实现代码:
1. 全局统计(不关联用户表,直接统计所有已填表单)
如果只是需要统计所有filled_forms里的销售数据数量和收入总和,代码可以这么写:
$overallStats = DB::table('filled_forms') ->select( // 统计sales为true时的value数量 DB::raw("COUNT(CASE WHEN sales = TRUE THEN value END) AS number_of_sales"), // 统计income为true时的value总和 DB::raw("SUM(CASE WHEN income = TRUE THEN value END) AS income") ) ->first();
这里的核心逻辑是:
CASE WHEN会只对满足条件的行返回对应的value,不满足条件的行返回NULLCOUNT函数会自动忽略NULL值,所以只会统计符合sales=true的有效记录数SUM函数同理,只会累加符合income=true的value值
2. 关联用户表的分组统计(按用户分别统计)
如果需要和user表关联,按每个用户来统计他的销售数据数量和收入总和,假设两张表通过user.id和filled_forms.user_id关联,代码如下:
$userStats = DB::table('user') ->leftJoin('filled_forms', 'user.id', '=', 'filled_forms.user_id') ->select( // 可以加上用户的基础字段,方便对应数据 'user.id', 'user.name', DB::raw("COUNT(CASE WHEN filled_forms.sales = TRUE THEN filled_forms.value END) AS number_of_sales"), DB::raw("SUM(CASE WHEN filled_forms.income = TRUE THEN filled_forms.value END) AS income") ) ->groupBy('user.id', 'user.name') ->get();
用leftJoin可以确保即使某个用户没有任何已填表单,也会出现在结果里;如果想把空值的收入总和显示为0,可以把SUM部分改成DB::raw("COALESCE(SUM(CASE WHEN filled_forms.income = TRUE THEN filled_forms.value END), 0) AS income")。
补充说明
你也可以用Laravel查询构造器的其他方法来实现,但DB::Raw在这里能最直接地映射原生SQL的条件聚合逻辑,可读性和灵活性都很高。如果你的数据库里布尔类型存储的是1/0而不是TRUE/FALSE,把代码里的TRUE换成1就可以正常运行。
内容的提问来源于stack exchange,提问作者PrStandup
相关产品推荐
相关产品推荐

