SQL Server:检查先前记录的日期

时间:2018-07-13 21:48:43

标签: sql sql-server

我有一个SQL Server表,每当有人签出并签入卡时,该表就将事务存储在数据库中。我试图提出一种视图,以显示某人在结帐后7天内没有办理登机手续的所有卡交易。我的表格如下所示:

+-------------+-------------+------------------+
| 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的记录,但是由于某些原因,我无法找到完成此工作的好方法。任何帮助,将不胜感激。先感谢您。

4 个答案:

答案 0 :(得分:0)

NOT EXISTS是我想到的第一件事:

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)
                 );

答案 1 :(得分:0)

select * from T t
where status = 'out' and not exists (
    select 1 from T t2
    where t2.card = t.card
        and t2.status = 'in'
        and t.dt between t2.dt and dateadd(day, 6, t.dt)
);

答案 2 :(得分:0)

您是否研究过SQL Server LEAD / LAG函数?这些可以轻松访问上一行或下一行。

示例:

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          |
+-------------+-------------+------------+---------------+---------------+

答案 3 :(得分:0)

不确定我是否做对了,但这就是我尝试过的。希望对您有帮助!

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'