【发布时间】:2014-10-25 08:10:53
【问题描述】:
在 API 文档中指定
- 的关系列表
$joinWith- 此查询应加入与$with- 此查询应该执行的关系列表
这些ActiveQuery属性有什么区别,在什么情况下应该使用$joinWith和$with?
【问题讨论】:
在 API 文档中指定
- 的关系列表
$joinWith- 此查询应加入与$with- 此查询应该执行的关系列表
这些ActiveQuery属性有什么区别,在什么情况下应该使用$joinWith和$with?
【问题讨论】:
请注意,除了上述帮助我弄清楚如何使用 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]);
【讨论】:
joinWith 使用 JOIN 将关系包含在原始查询中,而 with 没有。
为了进一步说明,请考虑具有关系 comments 的类 Post,如下所示:
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 时,您可以按关系排序 by/filter/group。您可能必须自己消除列名的歧义。
参考:http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#lazy-eager-loading
【讨论】:
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)
【讨论】:
joinWith 仍然会导致 2 个查询...原因我不太明白...我一直理解“SQL 查询越少越好”。因此,joinWith 只有在查询相关表中的列时才有用,否则只是一个缺点。
with 和 joinWith 之间的最大区别将在巨大的数据集上显着 - 例如在两个表之间连接数百万条记录比在索引列上进行简单的子查询(实际上是两个简单的查询)更加密集的操作。因此,在这种情况下使用更简单的with 很可能是更好的选择。