英文:
Why SQL Query with LEFT JOIN is giving this result?
问题
以下是您的MySQL查询的翻译部分:
SELECT distinct `b`.* FROM `books` `b`
LEFT JOIN `books_categories` `c`
ON c.id = b.category_id
LEFT JOIN `collections_has_books` `chb`
ON chb.book_id = b.id
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:
CREATE TABLE db.books (
id INT auto_increment not NULL,
title varchar(100) NULL,
category_id INT NULL,
PRIMARY key (id)
)
CREATE TABLE db.books_categories (
id INT auto_increment not NULL,
category varchar(100) NULL,
PRIMARY key (id)
)
CREATE TABLE db.collection (
id INT auto_increment not NULL,
title varchar(100) NULL,
PRIMARY key (id)
)
CREATE TABLE db.collections_has_books (
id INT auto_increment not NULL,
collection_id int not NULL,
book_id int not NULL,
PRIMARY key (id)
)
ENGINE=InnoDB
DEFAULT CHARSET=latin1
COLLATE=latin1_swedish_ci;
INSERT INTO db.books (title,category_id) VALUES
('Harry Potter and the philosopher''s stone',2),
('The lord of the rings',2),
('Moby dick',3),
('Robinson Crusoe',3),
('The Time Machine',1),
('The Great Gatsby',4),
('The Treasure Island',3);
INSERT INTO db.books_categories (category) VALUES
('science_fiction'),
('fanstasy'),
('adventures'),
('other');
INSERT INTO db.collection (title) VALUES
('books for vacations'),
('books for teenagers'),
('first readings'),
('books about adventrues and other stuff');
INSERT INTO db.collections_has_books (collection_id, book_id) VALUES
(1,1),
(1,4),
(1,5),
(2,1),
(2,2),
(2,4),
(3,4),
(3,5),
(4,4),
(4,5),
(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:
SELECT distinct `b`.* FROM `books` `b`
LEFT JOIN `books_categories` `c`
ON c.id = b.category_id
LEFT JOIN `collections_has_books` `chb`
ON chb.book_id = b.id
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。
select *
from books b
where not exists (
select chb.collection_id
from collections_has_books chb
where chb.book_id = b.id
and chb.collection_id = 2
)
这将包括那些不在任何收藏夹中的书籍,所以如果你只想要分配到收藏夹中的书籍,可能需要同时包括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.
select *
from books b
where not exists (
select chb.collection_id
from collections_has_books chb
where chb.book_id = b.id
and chb.collection_id = 2
)
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时更加清晰:
select *
from books b
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:
select *
from books b
LEFT JOIN `collections_has_books` `chb` ON chb.book_id = b.id
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论