MS Access SQL - 从5个表中搜索

时间:2015-04-03 10:24:56

标签: sql ms-access-2010

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

  
      
  1. BOOKS(book_id,book_name,book_rating)
  2.   
  3. 作者(author_id,author_name)
  4.   
  5. BOOK_AND_AUTHORS(ba_id,book_id,author_id)
  6.   
  7. 标签(tag_id,tag_name)
  8.   
  9. BOOKS_AND_TAGS(bt_id,book_id,tag_id)
  10.   

每本书都有一个或多个作者和一个或多个标签(对它们进行分类)。 BOOKS_AND_AUTHORSBOOKS_AND_TAGS是用于维护图书:作者和图书:标签之间多对多关系的联结表。

现在我想做的是使用多个标准搜索带有sql的特定书籍。

例如,我想获得符合以下条件的图书的名称和ID,

  
      
  1. 评分为2分或以上
  2.   
  3. 应该只有标签id' s 2和219表示的标签;没有其他标签允许。
  4.   

我的解决方案包括以下内容。

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实现此类搜索的任何建议?感谢。

1 个答案:

答案 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子句已分为两部分。