SQL Server:检查上一条记录的日期
我有一个SQL Server表,每当有人签出和签入卡片时,它都会在数据库中存储事务。我试图提出一个视图,以显示所有的卡交易,其中一个人没有签入一张卡在7天内的结帐。我的桌子如下所示:SQL Server:检查上一条记录的日期,sql,sql-server,Sql,Sql Server,我有一个SQL Server表,每当有人签出和签入卡片时,它都会在数据库中存储事务。我试图提出一个视图,以显示所有的卡交易,其中一个人没有签入一张卡在7天内的结帐。我的桌子如下所示: +-------------+-------------+------------------+ | Card_Number | Status | Transaction_Date | +-------------+-------------+------------------+ | 1234
+-------------+-------------+------------------+
| Card_Number | Status | Transaction_Date |
+-------------+-------------+------------------+
| 123456 | Checked In | 7/8/2018 |
| 123456 | Checked Out | 7/1/2018 |
| 234567 | Checked In | 7/8/2018 |
| 234567 | Checked Out | 7/1/2018 |
| 456789 | Checked In | 7/5/2018 |
| 456789 | Checked Out | 7/1/2018 |
+-------------+-------------+------------------+
在本例中,我希望记录的卡号为123456和234567,但由于某些原因,我无法找到一个好方法来实现这一点。任何帮助都将不胜感激。先谢谢你 首先想到的是不存在:
select t.*
from t
where status = 'Checked Out' and
not exists (select 1
from t t2
where t2.card_number = t.card_number and
t2.status = 'Checked In' and
t2.transaction_date >= t.transaction_date and
t2.transaction_date < dateadd(day, 7, t.transaction_date)
);
您是否研究过SQL Server的超前/滞后功能?这些允许轻松访问上一行或下一行 例如:
DECLARE @data TABLE ( [card_number] VARCHAR(15), [status] VARCHAR(15), [transaction_date] DATETIME );
INSERT INTO @data (
[card_number], [status], [transaction_date]
) VALUES
( '123456', 'Checked In', '07/08/2018' )
, ( '123456', 'Checked Out', '07/01/2018' )
, ( '234567', 'Checked In', '07/08/2018' )
, ( '234567', 'Checked Out', '07/01/2018' )
, ( '456789', 'Checked In', '07/05/2018' )
, ( '456789', 'Checked Out', '07/01/2018' );
SELECT
[card_number]
, [status]
, CONVERT( VARCHAR(10), [transaction_date], 101 ) AS [txn_date]
, CONVERT( VARCHAR(10), LAG( [transaction_date], 1 ) OVER ( ORDER BY [card_number], [transaction_date] ), 101 ) AS [prev_txn_date]
, CONVERT( VARCHAR(10), LEAD( [transaction_date], 1 ) OVER ( ORDER BY [card_number], [transaction_date] ), 101 ) AS [next_txn_date]
FROM @data
WHERE
[card_number] = '123456'
ORDER BY
[card_number], [transaction_date];
返回:
+-------------+-------------+------------+---------------+---------------+
| card_number | status | txn_date | prev_txn_date | next_txn_date |
+-------------+-------------+------------+---------------+---------------+
| 123456 | Checked Out | 07/01/2018 | NULL | 07/08/2018 |
| 123456 | Checked In | 07/08/2018 | 07/01/2018 | NULL |
+-------------+-------------+------------+---------------+---------------+
不确定我是否做对了,但这就是我所尝试的。希望有帮助
select card_number, transaction_date, sta
from
(
select t1.card_number, t1.transaction_date, t1.sta, datediff(DAY, t1.transaction_date, t2.transaction_date) as diff
from trans t1
join trans t2
on t1.card_number = t2.card_number
) result
where diff=7 and sta = 'Checked Out'
嗨,戈登,你能再解释一下关于“不存在”的用法吗?我试过你的例子,但当我使用“不存在”时,我没有得到任何回报。如果我使用“Exists”,我会返回行。@Jestes。你的问题是,我正试图提出一个视图,以显示所有卡交易,其中一个人没有在结账后7天内签入卡。这表明不存在。这接近于我正在寻找的,但我不想有一个使用卡号的where语句。可以在where语句中使用lag或lead,以便在计算中比较日期吗?更不用说我能够使其工作并满足我的需要。谢谢你的帮助。回答你的问题,是的。你已经决定了,不客气。
select card_number, transaction_date, sta
from
(
select t1.card_number, t1.transaction_date, t1.sta, datediff(DAY, t1.transaction_date, t2.transaction_date) as diff
from trans t1
join trans t2
on t1.card_number = t2.card_number
) result
where diff=7 and sta = 'Checked Out'