在API文档中指定了
- 的关系列表
$joinWith
- 此查询应加入与$with
- 此查询应与执行的关系列表
这些ActiveQuery属性与我们应该在什么情况下使用$joinWith
和$with
有什么区别?
答案 0 :(得分:34)
joinWith
使用JOIN
在原始查询中包含关系,而with
则不包含。{/ p>
为了进一步说明,请考虑具有关系Post
的课程comments
,如下所示:
class Post extends \yii\db\ActiveRecord {
...
public function getComments() {
return $this->hasMany(Comment::className(), ['post_id' => 'id']);
}
}
使用with
以下代码:
$post = Post::find()->with('comments');
导致以下sql查询:
SELECT `post`.* FROM `post`;
SELECT `comment`.* FROM `comment` WHERE post_id IN (...)
下面是joinWith
代码:
$post = Post::find()->joinWith('comments', true)
导致查询:
SELECT `post`.* FROM post LEFT JOIN `comment` comments ON post.`id` = comments.`post_id`;
SELECT `comment`.* FROM `comment` WHERE post_id IN (...);
因此,当使用joinWith
时,您可以通过关系按/ filter / group排序。您可能必须自己消除列名称的歧义。
参考:http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#lazy-eager-loading
答案 1 :(得分:23)
with
和joinWith
使用with
方法会产生以下SQL查询
$users = User::find()->with('userGroup');
SELECT * FROM `user`;
SELECT * FROM `userGroup` WHERE userId = ...
...使用joinWith
时将导致此SQL查询
$users = User::find()->joinWith('userGroup', true)
SELECT * FROM user LEFT JOIN `userGroup` userGroup ON user.`id` = userGroup.`userId`;
所以我需要在相关表格中过滤或搜索数据时使用joinWith
。
docu - > http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#joining-with-relations会告诉你:
“使用关系数据库时,常见的任务是连接多个表并将各种查询条件和参数应用于JOIN SQL语句。而不是显式调用yii \ db \ ActiveQuery :: join()来构建在JOIN查询中,您可以重用现有的关系定义并调用yii \ db \ ActiveQuery :: joinWith()来实现此目标。“
这意味着,您现在可以自行处理joins
,innerJoins
,outerJoins
以及Yii2中所有相关的相关内容。 Yii(不是Yii2)仅使用join
而不让用户决定加入类型。有关“加入”的详细信息 - >它是一个基于SQL的东西。你可以在这里阅读http://en.wikipedia.org/wiki/Join_(SQL)
答案 2 :(得分:1)
请注意,除了以上令人敬畏的答案,帮助我弄清楚如何使用joinWith()
,每当你想使用joinWith()
并且你有不明确的列名时,Yii / ActiveRecord自动似乎选择一个随机列,而不是你通常所期望的(最左边的表)。最好通过指定SELECT
之类的内容在$query->select("post.*")
子句中指定最左边的表。我从一些内部表中获取了id,并且它们被用尽了它们从最左边的表中 ,直到我想出来。
另一点需要注意的是,你可以为joinwith关系指定一个别名,所以你可以这样说:
$post->find()
->joinWith(["user u"])
->where(["u.id"=>$requestedUser->id])
->select("post.*")
->orderBy(["u.created_at"=>SORT_DESC]);