亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Laravel Eloquent whereDoesntHave() 文檔讓我感到困惑

Laravel Eloquent whereDoesntHave() 文檔讓我感到困惑

PHP
泛舟湖上清波郎朗 2023-08-26 10:12:27
參考https://laravel.com/docs/7.x/eloquent-relationships#querying-relationship-absence查詢use Illuminate\Database\Eloquent\Builder;$posts = App\Post::whereDoesntHave('comments.author', function (Builder $query) {    $query->where('banned', 0);})->get();被描述為“檢索所有帶有未被禁止的作者評論的帖子”。這對我來說似乎是不正確的,因為這似乎意味著,如果一篇文章有來自被禁止作者的一條評論和來自非被禁止作者的另一條評論,那么該帖子將出現在結果集合中 - 畢竟,它有來自被禁止作者的評論沒有禁止。實際上,由于存在被禁止的作者的評論,這樣的帖子不會被包含在集合中,無論該帖子可能有其他評論如何。似乎更準確的說法是“檢索所有有評論的帖子,其中沒有一個來自被禁止的作者”。我是不是弄錯了什么?
查看完整描述

1 回答

?
ITMISS

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 個結果。


這證明實際行為是“檢索所有沒有評論的帖子,或者所有評論都來自被禁止的作者”


查看完整回答
反對 回復 2023-08-26
  • 1 回答
  • 0 關注
  • 170 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號