1 回答

TA貢獻1871條經驗 獲得超8個贊
事實上,兩者都不正確。正確的說法是:
“檢索所有沒有評論的帖子,或者所有評論都來自被禁止的作者”
我為 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 }
? ? ? ?)
如果你想自己測試一下,
楷模:
<?php
namespace 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');
? ? }
}
<?php
namespace 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');
? ? }
}
<?php
namespace 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 post
INSERT 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 個結果。
這證明實際行為是“檢索所有沒有評論的帖子,或者所有評論都來自被禁止的作者”
- 1 回答
- 0 關注
- 170 瀏覽
添加回答
舉報