2015-04-03 2 views
1

У меня есть база данных, которая хранит информацию о электронных книгах и состоит из 5 таблиц, а именно,MS Access SQL - Поиск из 5 таблиц

  1. КНИГИ (book_id, book_name, book_rating)
  2. АВТОРОВ (AUTHOR_ID , author_name)
  3. BOOK_AND_AUTHORS (BA_ID, book_id, author_id)
  4. МЕТКИ (tag_id, имя_тега)
  5. BOOKS_AND_TAGS (bt_id, book_id, tag_id)

В каждой книге есть один или несколько авторов и один или несколько тегов (чтобы их классифицировать). BOOKS_AND_AUTHORS и BOOKS_AND_TAGS - это таблицы соединений, используемые для поддержания отношений «многие ко многим» между книгами: авторами и книгами: тегами.

Теперь я хочу найти конкретную книгу с sql, используя несколько критериев.

Например, я хочу, чтобы получить имена и корочку книги, которые соответствуют следующим критериям,

  1. Имеет рейтинг 2 или выше
  2. должны иметь только тег, обозначаемые тег идентификаторов 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

Вы можете упростить только присоединение к 2 таблицам, о которых вы говорите, а не все 5 – Randy

+0

@Randy Спасибо за комментарий. Не могу этого сделать, потому что это усложнит код (VBA). Я хочу, чтобы вышеуказанный SQL выполнял поиск по любым критериям. Например, если я хочу искать книгу, используя имя автора + 5 тегов + имя частичной книги. – chemkatku

ответ

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 не будет оценен в ИСТИНУ для некоторых ожидаемых случаев. Это связано с тем, что в результирующем наборе, создаваемом операцией join, содержится много повторяющихся строк для данной книги. Поэтому в некоторых случаях часть 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 пункт был разделен на две части.

Смежные вопросы