比较同一个表sql中的下一条记录

时间:2016-03-10 12:18:53

标签: sql sql-server sql-server-2008-r2

我有一个表有2列trans_date和amount。 如果记录的传输差异和下一条记录是1天或同一天,我想查询给出金额。

说明:

AMOUNT    TRANS_DATE

2645    2011-05-11 20:57:27.000
2640    2011-05-12 00:00:00.000
2645    2011-05-15 18:01:11.000
2645    2011-06-15 18:27:45.000
2645    2011-06-16 17:06:33.000
2645    2011-06-18 15:19:19.000
2645    2011-06-23 15:42:18.000

查询应该只显示

 AMOUNT    TRANS_DATE

    2645    2011-05-11 20:57:27.000
    2640    2011-05-12 00:00:00.000
    2645    2011-05-15 18:01:11.000
    2645    2011-06-15 18:27:45.000
    2645    2011-06-16 17:06:33.000

我所有尝试的都是

select DATEDIFF(DAY,a.TRANS_DATE,b.TRANS_DATE) from FIN_AP_PAYMENTS a inner join ( select * from (select a.*,rank() over (order by id) as ra from FIN_AP_PAYMENTS a, FIN_AP_PAYMENTS b )tbl )



select a.TRANS_DATE,b.TRANS_DATE,rank() over (order by a.id) as ra1,rank() over (order by b.id) as ra2 from FIN_AP_PAYMENTS a,FIN_AP_PAYMENTS b



select DATEDIFF(day,tbl.TRANS_DATE,tbl2.TRANS_DATE) from (select a.*,rank() over (order by id) as ra from FIN_AP_PAYMENTS a) tbl inner join (select a.*,rank() over (order by a.id) as ra1 from FIN_AP_PAYMENTS a ) tbl2 on tbl.id=tbl2.id

2 个答案:

答案 0 :(得分:1)

使用lead()lag()获取下一个和上一个值。然后检查它们之间的时间进行过滤:

select t.amount, t.trans_date
from (select t.*, lead(trans_date) over (order by trans_date) as next_td,
             lag(trans_date) over (order by trans_date) as prev_td
      from FIN_AP_PAYMENTS t
     ) t
where datediff(second, prev_td, trans_date) < 24*60*60 or
      datediff(second, trans_date, next_trans_date) < 24*60*60;

编辑:

在SQL Server 2008中,您可以使用outer apply

执行此操作
select t.amount, t.trans_date
from (select t.*, tlead.trans_date as next_td,
             tlag.trans_date as prev_td
      from FIN_AP_PAYMENTS t outer apply
           (select top 1 t2.*
            from FIN_AP_PAYMENTS t2
            where t2.trans_date < t.trans_date
            order by trans_date desc
           ) tlag outer apply
           (select top 1 t2.*
            from FIN_AP_PAYMENTS t2
            where t2.trans_date > t.trans_date
            order by trans_date asc
           ) tlead         
     ) t
where datediff(second, prev_td, trans_date) < 24*60*60 or
      datediff(second, trans_date, next_trans_date) < 24*60*60;

答案 1 :(得分:0)

在SQL Server 2012之前,您可以使用ROW_NUMBERself joins的组合,而不是LEAD和LAG。

示例

WITH Example AS
    (
        SELECT
            ROW_NUMBER() OVER (ORDER BY Trans_Date) AS rn,              
            r.*
        FROM
            (
                VALUES
                    (2645, '2011-05-11 20:57:27.000'),
                    (2640, '2011-05-12 00:00:00.000'),
                    (2645, '2011-05-15 18:01:11.000'),
                    (2645, '2011-06-15 18:27:45.000'),
                    (2645, '2011-06-16 17:06:33.000'),
                    (2645, '2011-06-18 15:19:19.000'),
                    (2645, '2011-06-23 15:42:18.000')
            ) AS r(Amount, Trans_Date)
    )
SELECT
    curr.*,
FROM
    Example AS curr
        LEFT OUTER JOIN Example AS prv      ON prv.rn = curr.rn - 1
        INNER JOIN Example AS nxt           ON nxt.rn = curr.rn + 1
WHERE       
    DATEDIFF(DAY, curr.Trans_Date, nxt.Trans_Date) IN (0, 1)
    OR DATEDIFF(DAY, prv.Trans_Date, curr.Trans_Date) IN (0, 1)
;

CTE允许您多次重复使用行号。行号提供自连接的序列。连接允许您在同一行上查看上一个和下一个值,以进行比较。

此查询的输出与您的示例不符,请参阅评论中的我的问题以获取更多相关信息。

我不确定告诉那些放弃时间帮助你的人,你在这里或不在这里讨论的是一个好主意。这肯定让我在发帖前三思而行。