【问题标题】:Can't figure out how to find how many books were loaned by each library branch不知道如何找到每个图书馆分馆借出多少本书
【发布时间】:2022-09-23 22:34:53
【问题描述】:

两个表之间的关系是,

CREATE TABLE library_branch 
(
    branchID NUMBER, 
    branchName varchar(20), 
    address varchar(20), 
    PRIMARY KEY(branchID)
)

CREATE TABLE book_loan 
(
    bookID varchar(20), 
    branchID NUMBER, 
    cardNo NUMBER, 
    dateOut DATE, 
    dueDate DATE, 
    PRIMARY KEY(bookID, branchID, cardNo), 
    FOREIGN KEY(branchID) REFERENCES library_branch(branchID)
)

问题是:对于每个图书馆分馆,检索分馆名称和从该分馆借出的图书总数

我写了一个查询来找出哪个图书馆分馆借了哪些书,但不知道如何找到每个图书馆分馆借了多少本书。

任何解决此问题的帮助将不胜感激。

  • 附带说明: book_loan 的主键有点奇怪。它似乎允许您一生中只从分支机构借一次每本书(每个 cardno 一次)。

标签: sql oracle


【解决方案1】:

“每个分支的书籍”在 SQL 中转换为 GROUP BY branchid。好吧,“多少”是COUNT(*)。您可以从 book_loan 表中获得该信息。要了解目前借出多少本书,请查看日期。相关贷款的 dateOut 日期为今天或过去,dueDate 日期为未来。

在 Oracle 中,您可以使用TRUNC(SYSDATE) 获得当天。

最后,您需要有关分支本身的信息。因此,从分支表中选择该信息,然后加入获取每个分支计数的子查询。使用外部连接以包括当前没有借出任何书籍的分支。

select b.branchid, b.branchname, coalesce(l.loaned, 0) as currently_loaned
from library_branch b
left outer join
(
  select branchid, count(*) as loaned
  from book_loan
  where dateout <= trunc(sysdate)
  and duedate > trunc(sysdate)
  group by branchid
) l on l.branchid = b.branchid
order by b.branchid;

【讨论】:

    【解决方案2】:
    select count(bookId), branchName from library_branch
    left outer join book_loan on book_loan.branchId = library_branch.branchId
    group by branchName
    

    这选择全部library_branch 中的行,然后将这些行与 book_loan 中的任何匹配行连接起来。 然后它计算任何具有非空 bookId 的行,并按分支对这些计数求和。

    请注意,count(*) 是不正确的,因为即使没有借出任何书籍,它也会为每个分支返回至少 1。

    【讨论】:

    • 这将返回每个分支机构的贷款总数,而不是借出的书籍总数:如果一本书被借出两次,它将被计算两次
    • @re_arg:这里的问题有点模棱两可。如果一个分行每天借10本书,我们可以说他们每月借300本书,不管他们是否一次又一次地借相同的书。因此,您只是对问题的解释与个人主义者不同。我的解释还是不一样,因为当我被问到分行借了多少本书时,我会回答目前借了多少。
    • @个人主义者:是LEFT [OUTER] JOIN。所以关键字LEFT是必须的,只有关键字OUTER是可选的。尽管 bookid 和 branchname 仅出现在其中一张表中,但在处理多个表时,仍建议使用其表名限定所有列。表别名有助于提高可读性。
    【解决方案3】:

    从你的查询开始,知道哪些书是从哪个分行借来的,下一步是通过...分组分支和数数借出的书籍数量。这可以通过以下方式实现:

    SELECT branchName, COUNT(DISTINCT bookId) as booksLoaned
    FROM library_branch lb INNER JOIN book_loan bl ON lb.branchId = bl.branchId
    GROUP BY branchName
    

    我使用了DISTINCT,因为您提到您需要借出的书籍数量而不是借出的数量,因此每个bookId 只计算一次。如果您需要贷款总数,您可以直接使用COUNT

    编辑:

    SELECT branchName, COUNT(DISTINCT bookId) as booksLoaned
    FROM library_branch lb LEFT OUTER JOIN book_loan bl ON lb.branchId = bl.branchId
    GROUP BY branchName
    

    如果您还想归还没有借出任何书籍的分支机构,请将inner join 更改为left outer join

    【讨论】:

    • 嗨,它是 COUNT(DISTINCT bookId),而不是 COUNTDISTINCT(bookId)。尽管 bookid 和 branchname 仅出现在其中一张表中,但在处理多个表时,仍建议使用其表名限定所有列。
    • 谢谢,我已经在答案中修复了DISTINCT。我看到 Oracle 有一个 COUNTDISTINCT 函数,但它仅适用于 Endeca EQL
    猜你喜欢
    • 2015-05-27
    • 2013-10-15
    • 2014-11-12
    • 2013-12-16
    • 1970-01-01
    • 2022-07-20
    • 1970-01-01
    • 2021-02-15
    • 2017-11-30
    相关资源
    最近更新 更多