我正在为我的学校设计一个图书馆应用程序。我们有2-3个主要的库,有些部门有自己的库。我想知道这些查询是否正确?
Libraries
ID Name
1 Walter
2 Wally
3 Maths dept library
Books
ID Book ID BookName
1 1 Fundamentals of calculus
2 1 Mechanics
3 2 Fundamentals of calculus
4 2 Biology
Lib_Book_LookUp
ID libId bookId
1 1 1
2 1 2
3 2 1
4 2 2
我想解决的两个问题是:
这就是我所拥有的:
Select count(Book.bookId) where book.name = "Fundamentals of calculus";
Select count(libId) from Lib_Book_lookUp, Book where Book.BookId = Lib_Book_lookUp.bookId groupBy(libId)
我对这些问题的疑问:
答案 0 :(得分:4)
您的第一个查询缺少FROM
子句。您也可以COUNT(*)
,但在这种情况下并不特别重要:
SELECT count(Book.bookId) FROM Books WHERE BookName = "Fundamentals of calculus";
要找出哪些图书馆有特定图书,您不需要COUNT()
汇总。相反,您需要加入WHERE
子句。 COUNT()
会告诉您有多少图书馆有图书,但哪些图书馆。为此,您需要一个返回Libraries.Name
的查询。
SELECT
/* Return library names */
Libraries.Name
FROM
Libraries
/* Join through your lookup table to match a book name to a library name */
JOIN Lib_Book_LookUp ON Libraries.ID = Lib_Book_LookUp.libId
JOIN Books ON Books.ID = Lib_Book_LookUp.bookId
/* Which book to search for */
WHERE Books.BookName = 'Fundamentals of calculus'
查找表是合适的,因为它允许您将书籍规范化为Books
表中的单个记录(如果它存在于多个库中)。如你所知,没有真正的理由在Books
表中有多个副本,没有Book ID
列的原因。事实上,Book ID
列实际上是误导性的。有两种不同标题的书具有相同的标识1
。
Books
表确实应该如下所示,每本书标题一个记录(假设标题为权威,忘记了真正的权威性事项,如ISBN)
Books
ID BookName
1 Fundamentals of calculus
2 Mechanics
3 Biology
如果每个图书馆都有每本图书的多个副本,您可以考虑将每本图书的版本标准化为一个表格,以便通过图书馆条形码识别它们。然后,您将这些ID与库匹配为:
Books (defines bibliographic details)
ID BookName
1 Fundamentals of calculus
2 Mechanics
3 Biology
Book_Copies (Matches Books.ID to barcode, barcode is Primary Key)
BookId Barcode
1 1234567
1 1234568
2 8654321
2 8654322
Lib_Book_LookUp (matches book copies to libraries, allowing multiple copies by barcode)
ID libId bookBarcode
1 1 1234567
2 1 1234568
3 2 8654321
4 2 8654322
例如,要查询每个图书馆每本图书的份数,您可以使用:
SELECT
Libraries.Name,
Books.BookName,
COUNT(*)
FROM
Libraries
JOIN Lib_Book_LookUp ON Libraries.ID = Lib_Book_LookUp.libId
JOIN Book_Copies ON Lib_Book_Lookup.bookBarcode = Book_Copies.Barcode
JOIN Books ON Book_Copies.BookId = Books.ID
GROUP BY
Libraries.Name,
Books.BookName
答案 1 :(得分:1)
关于数据库设计,您不需要在查找表上使用代理键。您可以简单地执行库的复合主键并预订:
Lib_Book_LookUp libId bookId 1 1 1 2 2 1 2 2
我使用您的图书ID进行了以下更改(力学和生物学具有相同的ID):
Books ID Book ID BookName 1 1 Fundamentals of calculus 2 2 Mechanics 3 1 Fundamentals of calculus 4 3 Biology
在第一个查询中,您没有指定语句引用的表(FROM books
):
SELECT COUNT(bookId)
FROM books <= Table Reference
WHERE BookName = "Fundamentals of calculus";
在第二个查询中,您使用隐式语法来连接表。您应该像这样练习显式连接:
SELECT Lib_Book_LookUp.libId, Libraries.Name
FROM Lib_Book_LookUp
INNER JOIN Libraries ON Libraries.ID = Lib_Book_LookUp.libId
WHERE bookId IN
(SELECT DISTINCT bookId
FROM books
WHERE BookName = "Fundamentals of calculus")
此查询加入Libraries
和Lib_Book_LookUp
表,然后查找正在搜索该书的bookId
的库。
答案 2 :(得分:-1)
您的图书表看起来更像是“图书实例”表格。因此,它不应该有书名。无论是那个,还是BookID
列都是多余的。
您的第二个查询是正确的,如果您从1988年编写SQL 。如果没有,您应该使用join
语法。