簡體   English   中英

Activerecord Left Outer Join不使用NOT條件

[英]Activerecord Left Outer Join not working with NOT condition

此查詢有效:

person.posts.includes(:categories).
references(:categories).where(categories: { id: 20 })

但是在NOT條件下:

person.posts.includes(:categories).
references(:categories).where.not(categories: { id: 20 })

第二個查詢完成沒有錯誤 - 但沒有對結果進行過濾 - 因此它返回所有帖子。

MySQL:

SELECT COUNT(DISTINCT `posts`.`id`) FROM `posts` 
LEFT OUTER JOIN `category_manifests` ON `category_manifests`.`post_id` = `posts`.`id` 
LEFT OUTER JOIN `categories` ON `categories`.`id` = `category_manifests`.`category_id` 
WHERE `posts`.`person_id` = 14 AND (`categories`.`id` != 20)

我沒有在Activerecord文檔中找到任何建議,這是不可能的 - 我在這里遺漏了一些基本的東西嗎?

可能是每個帖子都出現在該連接表中其中連接表中的行具有categories.id <> 20.連接表最終看起來像這樣:

foos.id foos.name bars.id bars.name
1       qux       5       bux
2       qaz       5       bux
1       qux       6       bax
2       qaz       6       bax
3       qiz       5       bux

假設您想要與條形圖5連接的foos。

如果你說,對於這個示例表,給我不同的foos.id,其中bars.id = 5你會得到這些行:

1       qux       5       bux
2       qaz       5       bux
3       qiz       5       bux 

它給你foos.ids 1,2,3。

如果你然后說“給我不同的foos.id where bars.id <> 5”,你可能會直覺地認為你得到的全套foo id減去你從前一個查詢得到的那些,即[]。 你認為你在問“給我沒有加入5號欄的foos”。 但你得到的是這些行:

1       qux       6       bax
2       qaz       6       bax

因為這些是bars.id <> 5的行,而這些行的foos.ids是[1,2]。 這似乎與您的情況類似。

換句話說,您希望“帖子未加入第20類”,但您實際要求的是“加入到沒有ID 20的類別的帖子”。 從邏輯上講,這略有不同。

同意Max。 我會像這樣構造這種情況:

.where("NOT EXISTS (
  SELECT * FROM category_manifests 
  WHERE post_id = posts.id AND category_id = ?)", 
    excluded_category.id) 

相反,只是因為這種方式你不能在連接表數學中糾纏不清。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM