在选择中求和多个ActiveQuery子查询

时间:2018-07-11 01:31:55

标签: php activerecord yii2

我有下表

产品

id name 
1  Alcohol
2  Candy
3  Soda

ProductIn

id item_no count date
1  1       10   2018/01/01
2  1       20   2018/01/07
3  2       10   2018/01/08
4  3       10   2018/01/08

ProductOut

id item_no count date 
1  1       10   2018/01/02 
2  1       10   2018/01/09 
3  2       2    2018/01/09
4  3       3    2018/01/11

我想获得产品实际数量的总和 通过

select *, 
  (sum(select sum(count) from ProductIn where ProductIn.item_no = product.itemno) -
   sum(select sum(count) from ProductOut where ProductOut.item_no = product.itemno)) as availableQty
from product

目前,我正在像使用ActiveQuery一样

$main_query = Product::find();

$data = [];
foreach ($main_query->all() as $model) {
    $query1 = ProductIn::find()
                ->filterWhere(['=', 'item_code', $model->item_no])
                ->asArray()->one();

    $query2 = ProductOut::find()
                ->filterWhere(['=', 'item_code', $model->item_no])
                ->asArray()->one();

    $allModels[$model->item_no] = ['item_no' => $model->item_no, 'name' => $model->name,  'availableQty' => ($query1 - $query2)];
}

但是在每条记录上循环很慢,我想结合使用3个ActiveQuery。

我能够通过使用

将子查询包含到main_query中
 $main_query->addSelect($query1)

但是我无法将两个子查询的差异作为一个字段。

在ActiveQuery上有什么方法可以做到吗?

2 个答案:

答案 0 :(得分:0)

这里有几条建议-

  1. 在forloop中不需要循环重复查询(即$ query1和$ query2)
  2. 借助item_codes,只需从$ main_query收集ProductInProductOut模型所需的所有ArrayHelper::getColumn
  3. 创建2个自定义数组以将item_code及其查询结果(数量/数量)存储在其中,并在您的foreach循环中使用该数组。

您会发现执行时差很大。

答案 1 :(得分:0)

您可以尝试以下查询:

$connection = \Yii::$app->db;
$model = $connection->createCommand('select *, 
  (sum(select sum(count) from ProductIn where ProductIn.item_no = product.itemno) -
   sum(select sum(count) from ProductOut where ProductOut.item_no = product.itemno)) as availableQty
from product');
$products = $model->queryAll();

您需要导入查询类:

use yii\db\Query;