首页 > 解决方案 > 组合 SQL 如何在图书馆中找到可供借阅的书籍?

问题描述

大学全新图书馆的数据库:

create table "Book" (
  "BookCode" varchar(10) primary key, 
  "BookTitle" varchar(10) not null
);
insert into "Book"("BookCode", "BookTitle") 
  values('Book1', 'Book one');
insert into "Book"("BookCode", "BookTitle") 
  values('Book2', 'Book two');
insert into "Book"("BookCode", "BookTitle") 
  values('Book3', 'Book three')
    
create table "BorrowBook" (
  "ID" bigint generated by default as identity primary key,
  "StudentID" varchar(10) not null,
  "BookCode" varchar(10) not null,
  "BorrowDate" date , "ReturnDate" date);
insert into "BorrowBook"("StudentID", "BookCode", "BorrowDate", "ReturnDate")
  values('S1', 'B1', '2021-1-1', '2021-1-3');
insert into "BorrowBook"("StudentID", "BookCode", "BorrowDate", "ReturnDate")
  values('S1', 'B1', '2021-1-4', '2021-1-6');
insert into "BorrowBook"("StudentID", "BookCode", "BorrowDate", "ReturnDate")
  values('S1', 'B1', '2021-1-7', null);
insert into "BorrowBook"("StudentID", "BookCode", "BorrowDate", "ReturnDate")
  values('S2', 'B2', '2021-1-1', '2021-1-3');
insert into "BorrowBook"("StudentID", "BookCode", "BorrowDate", "ReturnDate")
  values('S2', 'B2', '2021-1-4', '2021-1-6');

我只能得到无法借阅的 BookCode:

select distinct "BookCode"
from "BorrowBook"
where "BorrowDate" is not null and "ReturnDate" is null

组合 SQL 如何找到可供借阅的 BookCode、B2 和 B3(而 B1 无法借阅)?

标签: sqlfirebird

解决方案


我同意先生。施密茨。您在两个表中有不同的图书代码。正如您发布的那样,您将无法加入"BookCode"。所以假设"BookCode"在两个表中是相同的。

也严格回答你的问题

组合 SQL 如何找到可供借阅的 BookCode、B2 和 B3(而 B1 无法借阅)?

这意味着您只能获得可用或不可用的书籍列表,不知道哪个是哪个。这将是答案:

select distinct b."BookCode"/*change to * to see*/ 
from "BorrowBook" a, "Book" b
where 
a."BookCode"(+) = b."BookCode" and
(
  "ReturnDate" is null or a."BookCode" not in 
  (
    select "BookCode" 
    from "BorrowBook" 
    where "ReturnDate" is null
  )
);

这将使用 提供相同的输出distinct,简化查询,但使用更大的数据集(使用 来查看*):

"ReturnDate" is null or "ReturnDate" is not null

但同样,严格回答问题


假设您确实需要知道哪个是哪个:

-- add ===> a.*, <==== instead of the distinct, to see all
select distinct b."BookCode", case when ("ReturnDate" is null and "BorrowDate" is not null) then 'Not available' else 'Available' end
from "BorrowBook" a, "Book" b
where 
a."BookCode"(+) = b."BookCode" and
(
  "ReturnDate" is null or 
  a."BookCode" not in 
  (
    select "BookCode" 
    from "BorrowBook" 
    where "ReturnDate" is null
  )
);

推荐阅读