是否可以在Yii中的ActiveRecord中进行子查询?

我有这样的查询:

select * from table1 where table1.field1 in (select table2.field2 from table2)

我目前正在使用以下代码:

object1::model()->findAll(array('condition'=>'t.field1 in (select table2.field2 from table2)'))

[编辑]
我想知道是否有一种方法来构造子查询而不使用SQL,并且不使用连接。

有什么解决方案吗?

并提前感谢。

===============>>#1 票数:11 已采纳

首先按db字段查找doublets:

$model=new MyModel('search');
$model->unsetAttributes();

$criteria=new CDbCriteria();
$criteria->select='col1,col2,col3';
$criteria->group = 'col1,col2,col3';
$criteria->having = 'COUNT(col1) > 1 AND COUNT(col2) > 1 AND COUNT(col3) > 1';

获取子查询:

$subQuery=$model->getCommandBuilder()->createFindCommand($model->getTableSchema(),$criteria)->getText();

添加子查询条件:

$mainCriteria=new CDbCriteria();
$mainCriteria->condition=' (col1,col2,col3) in ('.$subQuery.') ';
$mainCriteria->order = 'col1,col2,col3';

如何使用:

$result = MyModel::model()->findAll($mainCriteria);

要么:

$dataProvider = new CActiveDataProvider('MyModel', array(
        'criteria'=>$mainCriteria,
));

资料来源: http//www.yiiframework.com/wiki/364/using-sub-query-for-doubletts/

===============>>#2 票数:6

不,没有办法使用Yii的CDbCriteriaCActiveRecord以编程方式构造子查询。 它看起来也不像查询生成器

但是,您仍然可以通过几种不同的方式执行子查询:

$results = Object1::model()->findAll(array(
  'condition'=>'t.field1 in (select table2.field2 from table2)')
);

你也可以做一个连接(可能会更快,子查询可能很慢):

$results = Object1::model()->findAll(array(
  'join'=>'JOIN table2 ON t.field1 = table2.field2'
);

您还可以使用findAllBySql执行直接SQL查询:

$results = Object1::model()->findAllBySql('
  select * from table1 where table1.field1 in 
  (select table2.field2 from table2)'
);

但是,你可以至少为这些提供一个漂亮的AR风格界面,如下所示:

class MyModel extends CActiveRecord {
  public function getResults() {
    return Object1::model()->findAll(array(
      'condition'=>'t.field1 in (select table2.field2 from table2)')
    );
  }
}

这样称呼:

$model = new MyModel();
$results = $model->results;

一个有趣的替代想法是使用Query Builder的CDbCommand或其他东西创建子查询,然后将生成的SQL查询字符串传递给CDbCritera addInCondition() 不确定这是否有效,但它可能:

$sql = Yii::app()->db->createCommand()
  ->select('*')
  ->from('tbl_user')
  ->text;
$criteria->addInCondition('columnName',$sql);

您始终可以扩展基本CDbCriteria类,以便以某种方式处理和构建子查询。 可能会发布一个很好的扩展你可以释放! :)

我希望有所帮助!

===============>>#3 票数:0

我知道这是一个旧线程,但也许有人(像我一样)仍然需要一个答案。

与先前的答案有关的小问题。 所以,这是我的增强功能:

$model=new SomeModel();
$criteria=new CDbCriteria();
$criteria->compare('attribute', $value);
$criteria->addCondition($condition);
// ... etc
$subQuery=$model->getCommandBuilder()->createFindCommand($model->getTableSchema(),$criteria)->getText();

$mainCriteria=new CDbCriteria();
$mainCriteria->addCondition($anotherCondition);
// ... etc

// NOW THIS IS IMPORTANT 
$mainCriteria->params = array_merge($criteria->params, $mainCriteria->params);

// Now You can pass the criteria:
$result = OtherModel::model()->findAll($mainCriteria);

  ask by Youcef04 translate from so

未解决问题?本站智能推荐: