Sql Yii:在加入之前执行where条件

Sql Yii:在加入之前执行where条件,sql,yii,yii2,Sql,Yii,Yii2,我当前的查询有问题 TableA::find() ->select('*') ->joinWith(['TableB']) ->joinWith(['TableC']) ->joinWith(['TableD']) ->where([TableA.attribute1=1 or TableA.attribute2=1]) ->andWhere([(further possible conditions on the other Tables)]) ->a

我当前的查询有问题

TableA::find()
->select('*')
->joinWith(['TableB'])
->joinWith(['TableC'])
->joinWith(['TableD'])
->where([TableA.attribute1=1 or TableA.attribute2=1])
->andWhere([(further possible conditions on the other Tables)])
->all()
SQL查询通常的执行顺序是
From(带连接)
,然后是
where

有没有办法在连接之前执行第一个where条件,以减少连接线的数量?差不多

TableA::find()
->where([TableA.attribute1=1 or TableA.attribute2=1])
->select('*')
->joinWith(['TableB'])
->joinWith(['TableC'])
->joinWith(['TableD'])
->andWhere([(further possible conditions on the other Tables)])
->all()

嗯,我认为这是最好的办法。但是,如果不打印关系
TableB
TabelC
中的数据(您只需获取有关where条件的数据),则可以这样设置关系:

TableA::find()
->joinWith('TableB', false) //dont load data from this relational table
->joinWith('TableC', false) //dont load data from this relational table
->joinWith(['TableD']) //load data from this relational table
->where([TableA.attribute1=1 or TableA.attribute2=1])
->andWhere([(further possible conditions on the other Tables)])
->all()

您可以修改用于联接表的条件

在SQL中,它将如下所示:

SELECT 
  * 
FROM 
  `tableA`
  JOIN `tableB` ON (
    `tableA`.`FK` = `tableB`.`PK` 
    AND `tableA`.`attr1` = 'someValue'
  ) 
  JOIN tableC ON (`tableB`.`FK` = `tableC`.`PK`)
SELECT 
  * 
FROM 
  (
    SELECT 
      * 
    FROM 
      `tableA` 
    WHERE 
      `attr1` = 'someValue'
  ) AS `tableA` 
  JOIN `tableB` ON (`tableA`.`FK` = `tableB`.`PK`)
要在Yii中实现这一点,您可以使用方法。如果只想对这一个查询应用此条件,可以使用
joinWith()
方法中的callback来修改用于join的查询

$query=TableA::find()
->加入([
'tableB'=>函数(\yii\db\ActiveQuery$query){
$query->onCondition(['tableA.attr1'=>'someValue']);
}
])
//... 查询的其余部分
另一个选项是在sql查询的FROM部分使用子查询,如下所示:

SELECT 
  * 
FROM 
  `tableA`
  JOIN `tableB` ON (
    `tableA`.`FK` = `tableB`.`PK` 
    AND `tableA`.`attr1` = 'someValue'
  ) 
  JOIN tableC ON (`tableB`.`FK` = `tableC`.`PK`)
SELECT 
  * 
FROM 
  (
    SELECT 
      * 
    FROM 
      `tableA` 
    WHERE 
      `attr1` = 'someValue'
  ) AS `tableA` 
  JOIN `tableB` ON (`tableA`.`FK` = `tableB`.`PK`)
在yii中:

$subQuery=TableA::find()
->选择(“*”)
->其中(['attr1'=>'someValue']);
$query=TableA::find()
->选择(“*”)
->from(['tableA'=>$subQuery])
->joinWith('tableB')
// ... 查询的其余部分

这种方法的主要缺点是,子查询中的临时表没有任何索引,因此联接和其他条件会变慢。如果tableA有很多行,并且您希望在联接之前应用的条件将显著减少行数,那么使用这种方法可能仍然是值得的。

遗憾的是,我需要表中的数据,但我发现这不是问题所在,而是之后的处理。但也许其他人需要这个,所以我会让它打开。