You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel查询同字段不同whereIn条件下的求和差值实现方法

原查询问题排查
  • 嵌套where子句中写selectRaw无效:where子句仅负责筛选行数据,不能定义字段别名,你声明的in、out别名在外部查询中无法被识别。
  • 并列where条件逻辑冲突:两个where是AND关系,相当于要求type同时属于两个无交集的集合,最终匹配到的行数为0,无法得到计算结果。
  • 使用SQL保留关键字作为别名:in是SQL原生保留关键字,直接用作别名会触发语法错误。
  • 不必要的groupBy:查询已经通过where('contact_id',$this->contact->id)固定了唯一的联系人ID,分组不会产生额外作用。
解决方案

方案1:单查询直接计算差值(性能最优)

采用条件聚合逻辑,将分类判断放到SUM函数内部,不需要全局过滤数据,一次查询即可得到结果:

$amount = Transaction::where('contact_id', $this->contact->id)
    ->where('date', '<', $from)
    ->selectRaw(
        "COALESCE(SUM(CASE WHEN type IN ('CreditNote', 'ReceiptVoucher') THEN amount ELSE 0 END), 0) - 
         COALESCE(SUM(CASE WHEN type IN ('DebitNote', 'PaymentVoucher') THEN amount ELSE 0 END), 0) as amount"
    )
    ->value('amount');

方案2:分开查询后手动计算差值(可读性最高)

如果更倾向于拆分逻辑降低维护成本,可以分别统计两类数据的和再做减法,Laravel的sum()方法会自动将空结果转为0,不需要额外处理空值:

// 统计Type A总和
$sumTypeA = Transaction::where('contact_id', $this->contact->id)
    ->where('date', '<', $from)
    ->whereIn('type', ['CreditNote','ReceiptVoucher'])
    ->sum('amount');

// 统计Type B总和
$sumTypeB = Transaction::where('contact_id', $this->contact->id)
    ->where('date', '<', $from)
    ->whereIn('type', ['DebitNote','PaymentVoucher'])
    ->sum('amount');

// 计算差值
$amount = $sumTypeA - $sumTypeB;

内容的提问来源于stack exchange,提问作者Lucid Polygon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 20:36:05