【问题标题】:MS Access SQL - Searching from 5 tablesMS Access SQL - 从 5 个表中搜索
【发布时间】:2015-04-03 10:24:56
【问题描述】:

我有一个存储电子书信息的数据库,它由 5 个表组成,即,

  1. 书籍(book_id、book_name、book_rating)
  2. 作者(作者 ID,作者姓名)
  3. BOOK_AND_AUTHORS(ba_id、book_id、author_id)
  4. 标签(tag_id,tag_name)
  5. BOOKS_AND_TAGS(bt_id、book_id、tag_id)

每本书都有一个或多个作者和一个或多个标签(对它们进行分类)。 BOOKS_AND_AUTHORSBOOKS_AND_TAGS 是连接表,用于维护 book:authors 和 books:tags 之间的多对多关系。

现在我要做的是使用多个条件使用 sql 搜索特定书籍。

例如,我想获取满足以下条件的书的名称和ID,

  1. 评级为 2 或以上
  2. 应该只有标签ID为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 实现这种类型的搜索?谢谢。

【问题讨论】:

  • 您可以简化为仅加入您正在谈论的 2 个表,而不是全部 5 个
  • @Randy 感谢您的评论。不能这样做,因为这样做会使代码(VBA)复杂化。我希望上述 SQL 根据任何条件执行搜索。例如,如果我想使用作者姓名 + 5 个标签 + 部分书名来搜索一本书。

标签: sql ms-access-2010


【解决方案1】:

我在网上搜索了一番后想出了一个解决方案。

问题是由五表连接和以下部分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 子句已被拆分为两个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-27
    • 2023-03-22
    • 2016-02-10
    • 1970-01-01
    • 2013-10-09
    相关资源
    最近更新 更多