我有三张包含书籍和标签的表格。一本书可以用几个标签标记。
我想要做的是过滤掉用'漫画'和'浪漫'标记的书籍。
如何构建正确的查询以查找第二本书?
..从书籍b,标签t,tags_to_books tb中选择book_id((查找 TAGS_ID'7'和'8'))..
表设计:
DROP TABLE IF EXISTS `books`;
CREATE TABLE `books` (
`book_id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`book_id`)
);
INSERT INTO `books` (`book_id`)
VALUES
(1),
(2),
(3);
DROP TABLE IF EXISTS `tags`;
CREATE TABLE `tags` (
`tag_id` int(11) NOT NULL AUTO_INCREMENT,
`tag_name` varchar(11) NOT NULL DEFAULT '',
PRIMARY KEY (`tag_id`)
);
INSERT INTO `tags` (`tag_id`, `tag_name`)
VALUES
(7,'Comics'),
(8,'Romance'),
(9,'Fantasy');
DROP TABLE IF EXISTS `tags_to_books`;
CREATE TABLE `tags_to_books` (
`book_id` int(11) NOT NULL,
`tag_id` int(11) NOT NULL
);
INSERT INTO `tags_to_books` (`book_id`, `tag_id`)
VALUES
(1,7),
(2,7),
(2,8),
(3,9);
答案 0 :(得分:2)
您可以使用类似这样的东西,它实际上与其他SQL语言中的交集运算符相同:
select comics.book_id from (
select b.book_id
from books b
join tags_to_books tb on tb.book_id = b.book_id
join tags t on tb.tag_id = t.tag_id
where t.tag_id = 7) as comics
join (
select b.book_id
from books b
join tags_to_books tb on tb.book_id = b.book_id
join tags t on tb.tag_id = t.tag_id
where t.tag_id = 8) as romance
on comics.book_id = romance.book_id
这可能会稍微优化一下,但想法是获取幻想中的所有书籍,然后是所有浪漫的书籍,然后归还两者中的书籍。如果您需要创建需要更多条件的查询,则只需复制JOIN子句并更新标记ID。
答案 1 :(得分:1)
如果我理解正确,同一本书可以多次出现在标签表中。正确的吗?
你有没有试过像
这样的东西SELECT book_id
FROM books
WHERE book_id NOT IN
(SELECT comics.book_id
FROM tags_to_books as comics
JOIN tags_to_books as romance
ON comics.book_id = romance.book_id
WHERE comics.tag_id = 7
AND romance.tag_id = 8)
答案 2 :(得分:0)
很难读懂但是:
SELECT B.book_id
FROM Books B INNER JOIN tags_to_books ttb
ON ttb.book_ID = b.book_ID
JOIN tags t
ON t.tag_ID = ttb.Tag_ID
WHERE t.tag_ID IN(7) AND t.tag_ID IN(8)
我没有编译过这个但它应该可以工作
如Joe所述,您可以通过tag_name
执行此操作SELECT B.book_id
FROM Books B INNER JOIN tags_to_books ttb
ON ttb.book_ID = b.book_ID
JOIN tags t
ON t.tag_ID = ttb.Tag_ID
WHERE t.tag_name = 'Comics' AND t.tag_name = 'Romance'
答案 3 :(得分:0)
如果您只需要book_id
(而不是书籍的名称或标签的文字,则可行(但如果您的标签数量不同,则需要更改下面描述的幻数)在您的查询中):
SELECT book_id FROM tags_to_books
WHERE tag_id IN (7, 8)
GROUP BY book_id
HAVING COUNT(DISTINCT book_id, tag_id) = 2;
2
是标记的数量,如果您的查询中有更多或更少的标记,则必须更改这些标记。
答案 4 :(得分:0)
这是sql:http://sqlfiddle.com/#!2/fc556/6 希望这有帮助