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有很多行,并且您希望在联接之前应用的条件将显著减少行数,那么使用这种方法可能仍然是值得的。遗憾的是,我需要表中的数据,但我发现这不是问题所在,而是之后的处理。但也许其他人需要这个,所以我会让它打开。