querys queryall query orderby findone datos php yii subquery yii-cactiverecord

php - queryall - yii2 base de datos



Sub-consultas ActiveRecord Yii (3)

¿Es posible realizar subconsultas en ActiveRecord en Yii?

tengo una consulta como esta:

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

Actualmente estoy usando el código de barbecho:

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

[Editar]
Me gustaría saber si hay una manera de construir la subconsulta sin usar SQL, y sin usar combinaciones.

Hay alguna solución ?

y gracias de antemano


No, no hay una forma de construir programáticamente una subconsulta usando el CDbCriteria y CActiveRecord de Yii . Tampoco parece que el Generador de consultas tenga una forma.

Sin embargo, aún puede hacer subconsultas de diferentes maneras:

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

También puede hacer una combinación (que probablemente será más rápida, las consultas secundarias pueden ser lentas):

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

También puede hacer una consulta SQL directa con findAllBySql :

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

Sin embargo, al menos puedes proporcionar una buena interfaz de estilo AR a estos, así:

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

Llamado así:

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

Una idea alternativa interesante sería crear su subconsulta utilizando el CDbCommand del Query Builder o algo así, y luego simplemente pasar la cadena de consulta SQL resultante a un CDbCritera addInCondition() ? No estoy seguro de si esto funcionará, pero podría:

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

Siempre puede extender la clase base CDbCriteria para procesar y crear subconsultas de alguna manera también. ¡Podría hacer una buena extensión que podría lanzar! :)

¡Espero que eso ayude!


Sé que este es un hilo antiguo, pero tal vez alguien (como yo) todavía necesita una respuesta.

Hay pequeños problemas relacionados con las respuestas anteriores. Entonces, aquí está mi mejora:

$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);


Primero encuentra dobletes por campos db:

$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'';

Obtener la subconsulta

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

Agregue la condición de subconsulta:

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

Cómo utilizar:

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

O:

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

Fuente: http://www.yiiframework.com/wiki/364/using-sub-query-for-doubletts/