代码之家  ›  专栏  ›  技术社区  ›  Paul

在yii2 activerecord中使用子查询进行更新

  •  0
  • Paul  · 技术社区  · 6 年前

    可以用吗 子查询 更新时 ActiveRecord ?

    我有一个 products 具有以下列的表

    id    number_of_orders
    1           3
    2           3
    3           2
    

    和一个 items 桌子

    id    product_id
    1         1
    2         1
    3         1
    4         2
    5         2
    6         2
    7         3
    8         3
    

    我想要的是

    UPDATE products
    SET number_of_orders = (
        SELECT COUNT(id) FROM items WHERE product_id = 1
    )
    WHERE id = 1
    

    我试过了

    $subquery = ItemsModel::find()
        ->select('COUNT(id)')
        ->where(['product_id' => 1]);
    
    ProductsModel::updateAll(
        [
            'number_of_orders' => $subquery
        ],
        [
            'id' => 1
        ]
    );
    

    $product = ProductsModel::findOne(1);
    $product->number_of_orders = $subquery;
    
    $product->save();
    

    但这些都不管用。

    有人知道要解决这个问题吗?

    结论:

    在我更新到 yii 2.0.14 .

    3 回复  |  直到 6 年前
        1
  •  2
  •   rob006    6 年前

    尝试将yii更新到最新版本。从2.0.14开始 yii\db\ExpressionInterface (包括) Query ActiveQuery )应该正确处理并以与 yii\db\Expression . 所以所有这些都应该在yi2.0.14或更高版本中工作:

    $subquery = ItemsModel::find()
        ->select('COUNT(id)')
        ->where(['product_id' => 1])
    
    ProductsModel::updateAll(
        ['number_of_orders' => $subquery],
        ['id' => 1]
    );
    
    $product = ProductsModel::findOne(1);
    $product->number_of_orders = $subquery;
    $product->save();
    
    ProductsModel::updateAll(
        ['number_of_orders' => new Expression('SELECT COUNT(id) FROM items WHERE product_id = 1')],
        ['id' => 1]
    );
    

    最后一个例子同样适用于早期版本的yii。

        2
  •  0
  •   Insane Skull    6 年前

    你可以使用 count() 以获取记录数。

    $itemCount = ItemsModel::find()
       ->where(['product_id' => 1]);
       ->count();
    
    $product = ProductsModel::findOne(1);
    $product->number_of_orders = $itemCount;
    $product->save();
    
        3
  •  0
  •   e-frank    6 年前

    我更喜欢:

    $model = ProductsModel::findOne(1);
    $model->updateAttributes(['number_of_orders' => ItemsModel::find()->where(['product_id' => 1])->count()]);
    

    或者你可以做

    $query = Yii::$app->db
            ->createCommand(sprintf('UPDATE %s SET number_of_orders=(SELECT COUNT(*) FROM %s WHERE product_id=:id) WHERE id=:id', ProductsModel::tableName(), ItemsModel::tableName()), [':id' => $id, ])
            ->execute();
    

    注:如果两个表相同,则必须执行以下操作:

    $query = Yii::$app->db
            ->createCommand(sprintf('UPDATE %s SET number_of_orders=(SELECT * FROM (SELECT COUNT(*) FROM %s WHERE product_id=:id) xxx) WHERE id=:id', ProductsModel::tableName(), ItemsModel::tableName()), [':id' => $id, ])
            ->execute();