ITMISS
事实上,两者都不正确。正确的说法是:“检索所有没有评论的帖子,或者所有评论都来自被禁止的作者”我为 Laravel 文档创建了这个拉取请求来更正措辞。从这样的调用生成的 sql 将如下所示:SELECT *FROM `posts`WHERE NOT EXISTS( SELECT * FROM `comments` WHERE `posts`.`id` = `comments`.`postId` AND EXISTS( SELECT * FROM `authors` WHERE `comments`.`authorId` = `authors`.`id` AND `banned` = 0))细分一下,内部查询说“找到与每个帖子相关的所有评论,其中该评论是由未被禁止的作者撰写的。 SELECT * FROM `comments` WHERE `posts`.`id` = `comments`.`postId` AND EXISTS( SELECT * FROM `authors` WHERE `comments`.`authorId` = `authors`.`id` AND `banned` = 0)然后,顶级查询说:“现在,给我上面子查询没有返回行的所有帖子”即,所有作者都被禁止,或者根本没有评论。 SELECT * FROM `posts` WHERE NOT EXISTS( {.. sub query above here } )如果你想自己测试一下,楷模:<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Model;use Illuminate\Database\Eloquent\Relations\HasMany;class Post extends Model{ public function comments(): HasMany { return $this->hasMany(Comment::class, 'postId'); }}<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Model;use Illuminate\Database\Eloquent\Relations\HasOne;class Comment extends Model{ public function author(): HasOne { return $this->hasOne(Author::class, 'id', 'authorId'); }}<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Model;class Author extends Model{}创建表Sql:CREATE TABLE `posts` ( `id` BIGINT NOT NULL AUTO_INCREMENT, PRIMARY KEY (`id`));CREATE TABLE `comments` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT, `postId` BIGINT(20) NOT NULL, `authorId` BIGINT(20) NOT NULL, `content` VARCHAR(50) NOT NULL, PRIMARY KEY (`id`));CREATE TABLE `authors` ( `id` BIGINT(20) NOT NULL AUTO_INCREMENT, `name` VARCHAR(50) NOT NULL, PRIMARY KEY (`id`));内容sql:# crate a postINSERT INTO `posts` (`id`) VALUES ('1');# add a banned and not banned author INSERT INTO `authors` (`name`, `banned`) VALUES ('Jack', '0');INSERT INTO `authors` (`name`, `banned`) VALUES ('Jill', '1');# add a comment from a banned and not banned author INSERT INTO `comments` (`postId`, `authorId`, `content`) VALUES ('1', '1', 'a');INSERT INTO `comments` (`postId`, `authorId`, `content`) VALUES ('1', '2', 'b');现在运行代码:$post = \App\Models\Post::whereDoesntHave('comments.author', function ( $query) { $query->where('banned', 0);})->get();您将得到 0 个结果。现在运行此命令以使两位作者都不会被禁止:UPDATE `authors` SET `banned`='0';您仍然会得到 0 个结果。现在运行这个命令来禁止两位作者:UPDATE `authors` SET `banned`='1';您现在将返回 1 个结果。现在运行此命令,使两位作者不再被禁止,但删除他们的评论:UPDATE `authors` SET `banned`='0';DELETE FROM `comments`;您现在将返回 1 个结果。这证明实际行为是“检索所有没有评论的帖子,或者所有评论都来自被禁止的作者”