Я строю базу данных библиотеки.
Я хочу написать запрос, который возвращает доступные книги в библиотеке (их 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 », результат будет правильным. Тем не менее, я также хочу, чтобы имена авторов в результате. В чем моя ошибка? Заранее спасибо!
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;
Все еще немного сбит с толку .. Не могли бы вы объяснить, где именно ошибка и как я могу это исправить?
На самом деле не подразумевается как ответ, так как этот «комментарий» слишком большой.
Но более корректное переписывание 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
...
...
...
Похожие вопросы
Новые вопросы
mysql
MySQL - это бесплатная система управления реляционными базами данных с открытым исходным кодом (RDBMS), использующая язык структурированных запросов (SQL). НЕ ИСПОЛЬЗУЙТЕ этот тег для других БД, таких как SQL Server, SQLite и т. Д. Это разные БД, которые все используют свои собственные диалекты SQL для управления данными.