我有两张桌子借书和书。我只需要选择免费书籍。 问题是当一本书被多次借用时,在我的代码中,select总是使我知道这本书是可用的,但是她又被借了,应该不可用。 我在MS SQL Server 2012 Express和SQL Server Management中使用了
。CREATE VIEW Free_Books AS
select distinct ID_book, Name_book, FirstName_writer, LastName_writer from Books
left join borrow on books.ID_book = borrow.ID_book
where date_borrow IS NOT NULL and date_returned IS NOT NULL
or
date_borrow is NULL and date_returned IS NULL
答案 0 :(得分:0)
从概念上讲,您首先需要仅获得最近借出的列表,然后仅显示尚未归还的那些。这应该可以在SQL Server和其他一些数据库中使用,但是正如@Mihai所述,如果我们知道您使用的是什么系统,我们可以提供更多帮助:
CREATE VIEW Free_Books
AS
WITH ListAll
AS (
SELECT DISTINCT
ID_book
,Name_book
,FirstName_writer
,LastName_writer
,date_borrow
,date_returned
,datum_borrow
,datum_returned
,RowNum = ROW_NUMBER()OVER(PARTITION BY ID_book ORDER BY date_borrow DESC /* this is the most recent borrow */)
FROM Books
LEFT JOIN borrow ON books.ID_book = borrow.ID_book
)
SELECT ID_book
,Name_book
,FirstName_writer
,LastName_Writer
FROM ListAll
WHERE ListAll.RowNum = 1 /* eliminate prior borrows */
AND date_borrow IS NOT NULL
AND date_returned IS NOT NULL
OR datum_borrow IS NULL
AND datum_returned IS NULL;
[由于后续问题而添加]
就个人而言,我会在您的视图中包括所有书籍,但会添加一个[IsAvailable]布尔标志:
CREATE VIEW All_Books
AS
WITH ListAll
AS (
SELECT DISTINCT
ID_book
,Name_book
,FirstName_writer
,LastName_writer
,datum_borrow
,datum_returned
,RowNum = ROW_NUMBER()OVER(PARTITION BY ID_book ORDER BY date_borrow DESC /* this is the most recent borrow */)
FROM Books
LEFT JOIN borrow ON books.ID_book = borrow.ID_book
)
SELECT ID_book
,Name_book
,FirstName_writer
,LastName_Writer
,[IsAvailable] = CAST(CASE WHEN datum_borrow IS NOT NULL AND datum_returned IS NULL THEN 0 ELSE 1 END AS BIT)
FROM ListAll
WHERE ListAll.RowNum = 1 /* Only the most recent record per book */;
您不希望数据库触发,因为只有在有人尝试借书时才会触发数据库:这不是很好的客户服务。理想情况下,您的前端应用程序将显示所有书籍,但已借用不同颜色(通常是灰色)的书籍。然后,客户可以查看现有书籍和现有书籍。
答案 1 :(得分:0)
不看表结构很难分辨,但是在我看来,您当前的查询正在加入给定书的所有过去“借阅”事件,而不仅仅是检查是否已返回自最近一次借用以来。我认为您应该尝试编写一个子查询,该子查询仅针对给定的书号选择具有最新借阅日期的行。然后,您可以将其添加到查询中,以检查书籍是否已退回。
答案 2 :(得分:0)
有效! @RussellFox代码很好!我的变量类型错误...当我将datum_borrow和datum_returned设置为datetime时,它就像瑞士时钟一样工作:) 谢谢大家的帮助!