SQL查询使用LEFT JOIN为什么会得到这个结果?

huangapple go评论101阅读模式
英文:

Why SQL Query with LEFT JOIN is giving this result?

问题

以下是您的MySQL查询的翻译部分:

  1. SELECT distinct `b`.* FROM `books` `b`
  2. LEFT JOIN `books_categories` `c`
  3. ON c.id = b.category_id
  4. LEFT JOIN `collections_has_books` `chb`
  5. ON chb.book_id = b.id
  6. WHERE (chb.collection_id != 2)

但我得到了以下结果:

[id] [title] [category_id]

1 Harry Potter and the philosopher's stone 2 <-- 我不明白为什么我会收到这个值,因为我使用了 WHERE (chb.collection_id != 2)

正如我所说,我不明白为什么我会得到 book Id = 1,因为它在 collection_id = 2 中。

请问有人能告诉我我做错了什么吗?

谢谢!

英文:

I have the following tables defined by:

  1. CREATE TABLE db.books (
  2. id INT auto_increment not NULL,
  3. title varchar(100) NULL,
  4. category_id INT NULL,
  5. PRIMARY key (id)
  6. )
  7. CREATE TABLE db.books_categories (
  8. id INT auto_increment not NULL,
  9. category varchar(100) NULL,
  10. PRIMARY key (id)
  11. )
  12. CREATE TABLE db.collection (
  13. id INT auto_increment not NULL,
  14. title varchar(100) NULL,
  15. PRIMARY key (id)
  16. )
  17. CREATE TABLE db.collections_has_books (
  18. id INT auto_increment not NULL,
  19. collection_id int not NULL,
  20. book_id int not NULL,
  21. PRIMARY key (id)
  22. )
  23. ENGINE=InnoDB
  24. DEFAULT CHARSET=latin1
  25. COLLATE=latin1_swedish_ci;
  26. INSERT INTO db.books (title,category_id) VALUES
  27. (&#39;Harry Potter and the philosopher&#39;&#39;s stone&#39;,2),
  28. (&#39;The lord of the rings&#39;,2),
  29. (&#39;Moby dick&#39;,3),
  30. (&#39;Robinson Crusoe&#39;,3),
  31. (&#39;The Time Machine&#39;,1),
  32. (&#39;The Great Gatsby&#39;,4),
  33. (&#39;The Treasure Island&#39;,3);
  34. INSERT INTO db.books_categories (category) VALUES
  35. (&#39;science_fiction&#39;),
  36. (&#39;fanstasy&#39;),
  37. (&#39;adventures&#39;),
  38. (&#39;other&#39;);
  39. INSERT INTO db.collection (title) VALUES
  40. (&#39;books for vacations&#39;),
  41. (&#39;books for teenagers&#39;),
  42. (&#39;first readings&#39;),
  43. (&#39;books about adventrues and other stuff&#39;);
  44. INSERT INTO db.collections_has_books (collection_id, book_id) VALUES
  45. (1,1),
  46. (1,4),
  47. (1,5),
  48. (2,1),
  49. (2,2),
  50. (2,4),
  51. (3,4),
  52. (3,5),
  53. (4,4),
  54. (4,5),
  55. (4,6);

and I want to obtain the all books included in other collections except collection id = 2, for that I write this MySQL request with LEFT JOINS:

  1. SELECT distinct `b`.* FROM `books` `b`
  2. LEFT JOIN `books_categories` `c`
  3. ON c.id = b.category_id
  4. LEFT JOIN `collections_has_books` `chb`
  5. ON chb.book_id = b.id
  6. WHERE (chb.collection_id != 2)

but I get those results:

[id] [title] [category_id]

1 Harry Potter and the philosopher's stone 2 <-- I can not understand why I am receiving this value if I put WHERE (chb.collection_id != 2)
4 Robinson Crusoe 3
5 The Time Machine 1
6 The Great Gatsby 4

As I said, I can not understand why I am getting the book Id = 1 if it is in a collection_id = 2.

Could please tell me someone what I am doing wrong?

Thank you!

答案1

得分: 1

如果一本书可以在多个收藏夹中,如果你想要排除在特定收藏夹中的书籍,应该使用NOT EXISTS。

  1. select *
  2. from books b
  3. where not exists (
  4. select chb.collection_id
  5. from collections_has_books chb
  6. where chb.book_id = b.id
  7. and chb.collection_id = 2
  8. )

这将包括那些不在任何收藏夹中的书籍,所以如果你只想要分配到收藏夹中的书籍,可能需要同时包括EXISTS/IN。

英文:

If a book can be in multiple collections. You should use NOT EXISTS if you want to exclude a book that is in a specific collection.

  1. select *
  2. from books b
  3. where not exists (
  4. select chb.collection_id
  5. from collections_has_books chb
  6. where chb.book_id = b.id
  7. and chb.collection_id = 2
  8. )

This will also include books that are not in any collections so you may need to include an EXISTS/IN as well if you only want books that are assigned to a collection

答案2

得分: 0

JamieD77也解释了。

我认为,当您执行以下SQL时更加清晰:

  1. select *
  2. from books b
  3. LEFT JOIN `collections_has_books` `chb` ON chb.book_id = b.id
英文:

JamieD77 explained it too.

I think it is more clear, when you execute these sql:

  1. select *
  2. from books b
  3. LEFT JOIN `collections_has_books` `chb` ON chb.book_id = b.id
  4. </details>

huangapple
  • 本文由 发表于 2023年3月3日 23:37:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/75629093.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定