Я строю базу данных библиотеки.

Я хочу написать запрос, который возвращает доступные книги в библиотеке (их isbns, названия, имена авторов, имя публикации, categoryName и количество доступных копий.

Мой запрос включает в себя следующие отношения (жирным шрифтом являются первичные ключи):

Книга (ISBN , title, pubYear, numpages, pubName ) pubName FK для издателя

копии (ISBN, copyNr , полка ) ISBN FK для бронирования

заимствует (memberID, ISBN, copyNr, date_of_borrowing , date_of_return ) memberID FK для участника, ISBN FK для книг, (ISBN, copyNr) FK для копий

assign_to (ISBN, categoryName) SBN FK для книги, categoryName FK для категории

writ_by (ISBN, authID) ISBN FK для книги, authID FK для автора

автор (authID , первый, последний, день рождения )

Мой подход следующий:

SELECT b.isbn, b.title,a.ALast, a.ALast, b.pubName, be.categoryName , COUNT(b.isbn) as Number_of_copies_available
FROM copies as c 
INNER JOIN book as b ON c.isbn = b.isbn 
INNER JOIN belong_to as be ON b.isbn = be.isbn 
INNER JOIN written_by as w ON w.isbn=b.isbn 
INNER JOIN author as a ON a.authID = w.authID
WHERE (c.isbn,c.copyNr) NOT IN (SELECT isbn, copyNr FROM borrows)
GROUP BY b.isbn
ORDER BY be.categoryName

Проблема в том, что я получаю повторяющиеся кортежи в результате перед группировкой, что приводит к увеличению количества элементов в группе.

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

Если у меня нет JOIN с отношениями «writ_by »и« author », результат будет правильным. Тем не менее, я также хочу, чтобы имена авторов в результате. В чем моя ошибка? Заранее спасибо!

-1
MJ13 27 Май 2019 в 18:56

2 ответа

Лучший ответ

Не присоединяйтесь к таблицам напрямую, если они не идеально связаны между собой. Категория книги на самом деле не связана с автором книги. С двумя авторами и двумя категориями, какого автора вы бы объединяли с какой категорией? Нет смысла объединять их (и, возможно, в конечном итоге со всеми комбинациями). Итак, сначала агрегируйте, а затем объединяйте. Вот пример:

select
  b.isbn,
  b.title,
  b.pubName,
  aut.authors,
  cat.categories,
  cop.total - coalesce(bor.total, 0) as available
from book b
join
(
  select w.isbn, group_concat(a.alast) as authors
  from  written_by w
  join author a ON a.authID = w.authID
  group by w.isbn
) aut ON aut.isbn = b.isbn
join
(
  select isbn, group_concat(categoryname) as categories
  from  belong_to
  group by isbn
) cat ON cat.isbn = b.isbn
join
(
  select isbn, count(*) as total
  from  copies
  group by isbn
) cop ON cop.isbn = b.isbn
left join
(
  select isbn, count(*) as total
  from  borrows
  where date_of_return > current_date
  group by isbn
) bor ON bor.isbn = b.isbn
order by b.isbn;
2
Thorsten Kettner 27 Май 2019 в 20:31

Все еще немного сбит с толку .. Не могли бы вы объяснить, где именно ошибка и как я могу это исправить?

На самом деле не подразумевается как ответ, так как этот «комментарий» слишком большой.

Но более корректное переписывание SQL 92 будет более или менее похоже на приведенное ниже.
Но так как вы не предоставили пример данных и ожидаемых результатов, я действительно догадываюсь, что вам нужно

Запрос

SELECT 
 book.isbn
 ...
FROM
 book
INNER JOIN (
  SELECT 
    COUNT(book.isbn) AS Number_of_copies_available
  FROM
   book
  INNER JOIN 
   copies
  ON
   book.isbn = copies.isbn

  ... # borrows table should also be needed here to be filterd? 
) AS book_copies__count
ON
...
...
...
1
Raymond Nijland 27 Май 2019 в 16:19
56329240