Почему я получаю дубликаты в моем запросе? - PullRequest
0 голосов
/ 27 мая 2019

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

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

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

Книга (ISBN , название, pubYear, номера, pubName ) pubName FK для издателя

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

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

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

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

автор (authID , AFirst, ALast, Abirthdate )

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

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 с отношениями "wrote_by" и "автор", тогда результат верен. Тем не менее, я также хочу, чтобы имена авторов в результате. В чем моя ошибка? Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 27 мая 2019

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

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;
1 голос
/ 27 мая 2019

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

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

Но более корректное переписывание 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
...
...
...
...