Sql 仅选择同一表中重复的最新记录
我有两张桌子和两本书。我只需要选择免费的书。 问题是当一本书被借了好几次,然后在我的代码中,select总是告诉我这本书是可用的,但是她又被借了,应该是不可用的。 Im使用带有SQL Server管理的MS SQL Server 2012 ExpressSql 仅选择同一表中重复的最新记录,sql,Sql,我有两张桌子和两本书。我只需要选择免费的书。 问题是当一本书被借了好几次,然后在我的代码中,select总是告诉我这本书是可用的,但是她又被借了,应该是不可用的。 Im使用带有SQL Server管理的MS SQL Server 2012 Express CREATE VIEW Free_Books AS select distinct ID_book, Name_book, FirstName_writer, LastName_writer from Books left join bor
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
从概念上讲,您需要首先获得一个仅包含最近借用的列表,然后只显示尚未归还的借用。这应该适用于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 */;
您不需要数据库触发器,因为只有在有人试图借书时才会触发:这不是很好的客户服务。理想情况下,您的前端应用程序将显示所有的书籍,但已借来的书籍颜色不同(通常为灰色)。然后,客户会看到现有的书籍以及现在可用的书籍。如果不查看您的表结构,就有点难以判断,但在我看来,您当前的查询似乎与所有过去的“借阅”关联起来了事件,而不仅仅是检查自最近一次借阅以来是否已归还。我认为您应该尝试编写一个子查询,只选择具有给定图书id的最新借阅日期的行。然后您可以将其添加到查询中,以便检查图书是否已归还。它可以工作@RussellFox代码很好!我有错误类型的变量。。。当我设置datum_forrow并将datum_返回为datetime时,它就像瑞士时钟一样工作:)
谢谢大家的帮助 请同时标记您正在使用的DBMS。示例数据和所需结果会有很大帮助。我感觉您的WHERE子句导致了这些问题-从您在不同行上分离的方式来看,它们似乎应该在每行上组合在一起。当你混合所有的and和OR而不分组时,你不会得到你想要的结果。如果你能发布一些示例数据/模式,有人会给你一个更好的答案。我使用的是带有SQL Server管理的MS SQL Server 2012 Express。谢谢所有的消息,我很抱歉信息不足,这是我的第一篇帖子:)非常感谢!!!这对我来说很有效,但当我尝试使用所有ID_book结果时,有一个问题总是会给我最后一条记录,但结果应该是零。我的错误日期和数据是一样的,返回的日期和返回的数据是一样的,我翻译了变量的名称以便更容易理解。我忘了问,如何在相同条件下触发触发器以避免借用已借用的书籍?即使现在变量“IsAvailable”中有了新代码,最后一本书也始终可用。我将数据库连接到access for gui,我想当我使用视图时,速度会慢一些,然后使用查询只选择免费书籍,然后使用下拉列表选择。我有两个表books and borrow,在书中我有(ID\u book,Name\u book,FirstName\u writer,LastName\u writer等),在借阅中我有(ID\u borrow,ID\u book,date\u borrow,date\u returned)它们通过ID_book)连接。我需要选择ID\u book、Name\u book、FirstName\u writer、LastName\u Write,当书空闲时(包括她是否从未借过书,以及她是否被借还。我希望你得到它:)