在同一表格中仅选择重复的最新记录

时间:2018-08-13 22:25:43

标签: sql

我有两张桌子借书和书。我只需要选择免费书籍。 问题是当一本书被多次借用时,在我的代码中,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

3 个答案:

答案 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时,它就像瑞士时钟一样工作:) 谢谢大家的帮助!