我有一个存储Ebooks信息的数据库,它由5个表组成,即
- BOOKS(book_id,book_name,book_rating)
- 作者(author_id,author_name)
- BOOK_AND_AUTHORS(ba_id,book_id,author_id)
- 标签(tag_id,tag_name)
- BOOKS_AND_TAGS(bt_id,book_id,tag_id)
醇>
每本书都有一个或多个作者和一个或多个标签(对它们进行分类)。 BOOKS_AND_AUTHORS
和BOOKS_AND_TAGS
是用于维护图书:作者和图书:标签之间多对多关系的联结表。
现在我想做的是使用多个标准搜索带有sql的特定书籍。
例如,我想获得符合以下条件的图书的名称和ID,
- 评分为2分或以上
- 应该只有标签id' s 2和219表示的标签;没有其他标签允许。
醇>
我的解决方案包括以下内容。
SELECT DISTINCT books.book_id, books.book_name
FROM
(
(tags INNER JOIN books_and_tags ON tags.tag_id = books_and_tags.tag_id)
INNER JOIN
(books INNER JOIN
(authors INNER JOIN books_and_authors
ON authors.author_id = books_and_authors.author_id)
ON books.book_id = books_and_authors.book_id)
ON books_and_tags.book_id = books.book_id
)
WHERE ((BOOKS.book_rating >= 2) AND ((TAGS.tag_id) IN (2,219)))
GROUP BY BOOKS.book_id, BOOKS.book_name
HAVING COUNT(TAGS.tag_id) = 2
不幸的是,这并不能归还我想要的东西。我做错了吗?有关如何使用SQL实现此类搜索的任何建议?感谢。
答案 0 :(得分:0)
我在网上搜索后找到了一个解决方案。
问题是由五个表连接和SQL语句的以下部分生成的:
WHERE ((BOOKS.book_rating >= 2) AND ((TAGS.tag_id) IN (2,219)))
GROUP BY BOOKS.book_id, BOOKS.book_name
HAVING COUNT(TAGS.tag_id) = 2
在加入了五个表之后,对于某些预期的情况,COUNT(TAGS.tag_id) = 2
将不会被评估为TRUE。这是因为在连接操作生成的结果集中,包含给定书籍的许多重复行。因此,COUNT...
部分在某些情况下会失败。为了解决这个问题,COUNT应该只考虑不同的tag_id。解决方案就像是,
HAVING COUNT (DISTINCT TAGS.tag_id) = 2
如果只有MS Access SQL引擎支持聚合函数内的DISTINCT
。有关详情,请参阅此处:How do I count unique items in field in Access query?
因此,我的最终解决方案是:
SELECT DISTINCT books.book_id, books.book_name
FROM
(SELECT DISTINCT tags.tag_id, books.book_id, books.book_name
FROM (
(tags INNER JOIN books_and_tags ON tags.tag_id = books_and_tags.tag_id)
INNER JOIN
(books INNER JOIN
(authors INNER JOIN books_and_authors
ON authors.author_id = books_and_authors.author_id)
ON books.book_id = books_and_authors.book_id)
ON books_and_tags.book_id = books.book_id
) WHERE (BOOKS.book_rating >= 2) [+ all the other conditions NOT based on tags]
)
WHERE (TAGS.tag_id) IN (2,219)
GROUP BY BOOKS.book_id, BOOKS.book_name
HAVING COUNT(TAGS.tag_id) = 2
请注意,原始WHERE
子句已分为两部分。