簡體   English   中英

MySQL左外連接,排除屬於用戶的第二個表中的項目

[英]MySQL Left Outer Join, Exclude Items in Second Table Belonging to User

我的MySQL數據庫中有兩個表,一個是數據庫中所有書籍的庫,另一個是包含對應於用戶庫中書籍的各個行。

例如:

圖書館表

 `id`        `title`...
=====        ===========
  1          Moby Dick
  2          Harry Potter

收集表

 `id`        `user`      `book`
=====        ======      =======
  1            1            2
  2            2            2
  3            1            1

我想要做的是運行一個查詢,顯示所有不在用戶集合中的書籍。 我可以運行此查詢來顯示不在任何用戶集合中的所有書籍:

SELECT * 
FROM  `library` 
LEFT OUTER JOIN  `collection` ON  `library`.`id` =  `collection`.`book` 
WHERE  `collection`.`book` IS NULL

據我所知,這很好用。 在PHPMyAdmin中運行此操作將導致所有不在集合表中的書籍。

但是,如何將其限制為某個用戶? 例如,上述虛擬數據,我想導致書1,如果用戶2運行查詢,並沒有書,如果用戶1運行查詢。

只是添加一個AND user=[id]不起作用,而且由於我對JOIN語句的了解非常有限,我真的無法實現。

此外,返回的結果的ID(顯示的查詢,不執行我想要但功能正常)是0 - 如何確保返回的ID是library.id的ID?

您必須將LEFT JOIN選擇范圍縮小到僅特定用戶擁有的書籍, 然后聯接表中的任何NULL都將是用戶在其集合中沒有的行(書籍):

SELECT
    a.id,
    a.title
FROM
    library a
LEFT JOIN
    (
        SELECT book
        FROM collection
        WHERE user = <userid>
    ) b ON a.id = b.book
WHERE 
    b.book IS NULL

另一種選擇是:

SELECT
    a.id,
    a.title
FROM
    library a
WHERE 
    a.id NOT IN
    (
        SELECT book
        FROM collection
        WHERE user = <userid>
    )

但是,第一個解決方案更加優化,因為MySQL將為每一行執行一次NOT IN子查詢,而不是僅對整個查詢執行一次。 直觀地說,你會期望MySQL一次執行子查詢並將其用作列表,但MySQL並不夠聰明,無法區分相關子查詢和非相關子查詢。

如前所述這里

“問題在於,對於使用IN子查詢的語句,優化器會將其重寫為相關子查詢。”

這個怎么樣? 它只是我的頭腦 - 我現在無法訪問數據庫進行測試。 (抱歉)

SELECT 
   * 
FROM 
   library lib 
WHERE 
   lib.id NOT IN (
      SELECT 
         book 
      FROM 
         collection coll 
      WHERE 
         coll.user =[id]
   )
;

暫無
暫無

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

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