简体   繁体   English

在Yii2 find()/ QueryBuilder中使用WHERE条件的SELECT子查询

[英]SELECT sub-query with WHERE condition in Yii2 find() / QueryBuilder

I was able to find simple examples of sub-query building, but am unable to figure out nor find the solution when I need to include a WHERE condition. 我能够找到子查询构建的简单示例,但是当我需要包含WHERE条件时,我无法弄清楚或找不到解决方案。 I am trying to simulate the following statement... 我试图模拟以下声明......

SELECT ParentTable.*, (SELECT MAX(ChildTable.NumberField) 
                       FROM ChildTable
                       WHERE ChildTable.FK_Id = ParentTable.Id)
FROM ParentTable

Guess I'd need something like... 猜猜我需要像......

$query = ParentClass::find()
        ->addSelect(
            ChildClass::find()
            ->where('childTable.fk_id=parentTable.id')
            ->max('childTable.field1')
        );

But it gives me an error: Column not found: 1054 Unknown column 'parentTable.id' in 'where clause' 但它给了我一个错误:找不到列:1054'where子句'中的未知列'parentTable.id'

EDIT: Including actual class/table names... 编辑:包括实际的类/表名...

$endQuery = UnitSchedule::find()
            ->where('cm_courseschedule.id=cm_unitschedule.csch_id')
            ->max('cm_unitschedule.slot');
$query = CourseSchedule::find();
$query->addSelect($endQuery);

The example query, from a SQL perspective is using a "correlated subquery" inside the select clause and often this is a very inefficient way of forming a query. 从SQL角度来看,示例查询在select子句中使用“相关子查询”,这通常是一种形成查询的非常低效的方法。

SELECT ParentTable.*, (SELECT MAX(ChildTable.NumberField) 
                       FROM ChildTable
                       WHERE ChildTable.FK_Id = ParentTable.Id)
FROM ParentTable

Although it may appear at first glance to be more complex and hence less efficient, it is generally better for performance to avoid "correlated subqueries" in a select clause and substitute using a "derived table" instead, like this: 虽然乍一看似乎更复杂,因此效率更低,但通常更好的性能是避免在select子句中使用“相关子查询”并使用“派生表”替换,如下所示:

SELECT ParentTable.*,c.MxNum
FROM ParentTable
LEFT JOIN (
           SELECT ChildTable.FK_Id, MAX(ChildTable.NumberField) as MxNum FROM ChildTable
           GROUP BY ChildTable.FK_Id
           ) AS c ON c.FK_Id = ParentTable.Id

Note, a correlated subquery with a select clause might return NULL, and due to this, if replacing them with a derived table the equivalent join type is a LEFT OUTER JOIN (or simply LEFT JOIN) as this also permits a NULL result. 注意,带有select子句的相关子查询可能返回NULL,因此,如果用派生表替换它们,则等效连接类型是LEFT OUTER JOIN(或简称为LEFT JOIN),因为这也允许NULL结果。 However if you don't need NULLs for the column, then use the more efficient INNER JOIN instead. 但是,如果列不需要NULL,则使用更高效的INNER JOIN。

Apologies in advance for not knowing Yii2 syntax, but it seems relevant to know an effective alternative approach which may assist in solving the issue. 因不了解Yii2语法而提前道歉,但知道有效的替代方法可能有助于解决问题。

Thanks Used_By_Already and Mike Ross, your replies helped me arrive at the final complete Yii2/MySQL solution below. 感谢Used_By_Already和Mike Ross,您的回复帮助我到达了下面的最终完整的Yii2 / MySQL解决方案。

$query = ParentClass::find();
$subQuery = ChildClass::find()->select('fk_id, max(column1) as column1')->groupBy('fk_id');
$query->leftJoin(['T' => $subQuery], 'T.fk_id = parentTable.id');

Try this because it works fine for me, i had similar situation where my table names are event and area_interest 试试这个,因为它适用于我,我有类似的情况,我的表名称是eventarea_interest

 $query = new Query();
 $subquery = new Query();
 $subquery ->select(['area_intrest.interest'])
            ->from('area_intrest' )
            ->where('area_intrest.id = event.interest_id');

 $query ->select(['event.title',$query3])
            ->from('event');
 $command = $query->createCommand();
 $data = $command->queryAll();

In your condition you can even use max in the subquery in quotes and it will work fine. 在您的情况下,您甚至可以在引号中的子查询中使用max ,它将正常工作。

Try this one 试试这个吧

$submodel = ChildClass::find()
          ->select([ 'ChildTable.fk_id', 'MAX(ChildTable.NumberField)', ])
          ->where("...")
          ->asArray();

$model    = ParentClass::find()
          ->select([ 'parentTable.*', 'b.*', ])
          ->innerJoin(['b' => $submodel], 'b.`fk_id` = parentTable.`id`')
          ->all();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM