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

Yii2中如何在SELECT语句内比较两个子查询的求和结果?

解决Yii2主查询筛选子查询聚合结果的问题

问题分析

你当前的问题在于直接在WHERE子句中使用子查询聚合结果进行筛选,而WHERE是分组前执行的,无法正确引用分组后的聚合值;同时当无匹配数据时,sum()会返回null,导致比较逻辑失效。

解决方案

需要做两点核心修改:

  1. 用COALESCE()处理聚合函数的null结果,转为0避免比较异常;
  2. 使用HAVING子句替代WHERE进行分组后的筛选(聚合结果的筛选必须在分组后执行)。

修改后的代码

1. 调整子查询,添加COALESCE处理空值

// 无匹配数据时返回0,避免null导致比较逻辑失效
$paidForOrder = (new Query())->select(['COALESCE(sum(amount*flow), 0)'])->from('moneyflow')->where('order_uid = i.uid');
$orderAmount = (new Query())->select(['COALESCE(sum(sale_price*qty*flow), 0)'])->from('salesflow')->where('order_uid = i.uid');

2. 主查询改用HAVING筛选聚合结果

$Query = (new Query())
    ->select([
        'i.uid as uid',
        'i.created as created',
        'i.ordernum as ordernum',
        'order_amount' => $orderAmount,
        'paid_for_order' => $paidForOrder,
    ])
    ->from('orders i')
    ->leftJoin('salesflow s','i.uid = s.order_uid')
    ->where(['i.type_id' => 2, 'i.customer_id' => $customer_id])
    ->groupBy('i.uid')
    ->having(['<', 'paid_for_order', 'order_amount']) // 通过SELECT中的别名筛选
    ->all();

备选方案(若数据库不支持HAVING用别名)

如果你的数据库不允许在HAVING中直接引用SELECT的别名,可以直接传入子查询对象:

->having(['<', $paidForOrder, $orderAmount])

或者直接写入完整SQL表达式:

->having('COALESCE((SELECT sum(amount*flow) FROM moneyflow WHERE order_uid = i.uid), 0) < COALESCE((SELECT sum(sale_price*qty*flow) FROM salesflow WHERE order_uid = i.uid), 0)')

内容的提问来源于stack exchange,提问作者Felix Abdullayev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 01:15:00