Yii2 merge queries like cdbcriteria in yii1

拥有回忆 提交于 2019-12-23 12:26:01

问题


I have a problem regarding merge of multiple queries. In Yii 1.x you could merge a CDbCriteria with

$criteria->merge($otherCriteria)

How can I achieve the same nested conditions etc with queries in Yii2?

Edit: Let's say I want separate queries to form subqueries. And after all subqueries are done I want to merge them together to the one big query.


回答1:


There is no CDbCriteria concept in Yii2 anymore. Instead you can refer to the following classes:

  • http://www.yiiframework.com/doc-2.0/yii-db-query.html (yii\db\Query)
  • http://www.yiiframework.com/doc-2.0/yii-db-activequery.html (yii\db\ActiveQuery)

All you did before with CDbCriteria now you can do with above classes. So, there will be no need to merge two criteria with each other.

update

Yii2 also supports sub-queries like below (as Yii2's official guide):

$subQuery = (new Query)->select('COUNT(*)')->from('user');
$query = (new Query)->select(['id', 'count' => $subQuery])->from('post');

Which results in:

SELECT `id`, (SELECT COUNT(*) FROM `user`) AS `count` FROM `post`

http://www.yiiframework.com/doc-2.0/guide-db-query-builder.html#building-query




回答2:


I also recently ran into this issue. Complete fusion of queries (select, join etc.) does not exist (as I understand it). But you can manually merge conditions, for example:

    $query1 = \app\models\User::find()
        ->where(['column1' => 'value1', 'column2' => 'value2']);

    $query2 = \app\models\User::find()
        ->where(['and', '[[column3]] = :column3', '[[column4]] = :column4'])
        ->addParams([
            ':column3' => 'value3',
            ':column4' => 'value4'
        ]);

    // merge conditions
    $query1->orWhere($query2->where);
    $query1->addParams($query2->params);

    // build SQL
    echo $query1->createCommand()->rawSql;

Built SQL:

SELECT * FROM `yii2_user` WHERE 
    ((`column1`='value1') AND (`column2`='value2')) OR 
    ((`column3` = 'value3') AND (`column4` = 'value4'))



回答3:


In addition to both the excellent answers above, should you need to merge two conditions to send on to a method which takes a 'condition' parameter in the same format as where(), then you can either build your own array:

$condition1 = ['column1' => 'value1', 'column2' => 'value2'];
$condition2 = ['column3' => 'value3', 'column4' => 'value4'];
$condition = [
    'or',
    $condition1,
    $condition2,
];
$model->updateAll([ 'column5' => 'value5' ], $condition);

Or, if it feels more logical, you can use a temporary query object to build the conditions up and merge, etc. Then pass the generated where condition from it, e.g.:

$query1 = new \yii\db\Query;
$query1->andWhere(['column1' => 'value1', 'column2' => 'value2']);
$query2 = new \yii\db\Query;
$query2->andWhere(['column3' => 'value3', 'column4' => 'value4']);
$query = new \yii\db\Query;
$query->where($query1->where)
      ->orWhere($query2->where);

$model->updateAll([ 'column5' => 'value5' ], $query->where);

Obviously, this makes more sense when the queries or conditions are built up elsewhere in the code and separately passed the the place where the model method is executed.



来源:https://stackoverflow.com/questions/27177329/yii2-merge-queries-like-cdbcriteria-in-yii1

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!