选择每个 dense_rank 的最后 2 行

Selecting last 2 rows of each dense_rank

我试图使用 MSSQL 从一个事件直接发生在另一个事件之后的日志中获取一些信息。

所以我的有效目标是获取一个由 TransactionID 分区的行号,然后我需要每个 transactionID 的最后 2 行(最后 2 行号)(按 TxnDate 字段排序)。每个 TransactionID 可以有任意数量的行。

所以我会得到:

JnlId    TxnId    RowNum
5        10001    65
2        10001    66
10       10002    11
8        10002    12
5        10003    15
98       10003    16

我不知道如何实现这一点,因为我不知所措!这之后的最终游戏是为 select 几个 ID 过滤掉 'JnlId' 字段。

有点背景故事。这位客户认为他们的员工在偷东西,所以我需要在他们直接取消商品时过滤掉,然后再完成每笔交易。

ascending 订单中 订购 而不是尝试 descending 订购

select * from 
(
select dense_rank() over(partition by transactionID Order by TxnDate Desc) Rn,*
from yourtable
) A
where rn<=2

只需按 RowNum 降序排序,然后 select ROW_NUMBER 小于或等于 2

DECLARE @Table TABLE
(
    JnlId INT
    , TxnId INT
    , RowNum INT
);

INSERT INTO @Table
    (JnlId, TxnId, RowNum)
VALUES
    (5, 10001, 65)
    , (2, 10001, 66)
    , (10, 10002, 11)
    , (8, 10002, 12)
    , (5, 10003, 15)
    , (98, 10003, 16);

SELECT T.JnlId, T.TxnId, T.RowNum
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY TxnId ORDER BY RowNum DESC) AS RowNo, *
FROM @Table) AS T
WHERE T.RowNo <=2

试试这个,我添加了一些额外的行以使密集排名更加明显:

测试数据:

DECLARE @t table(JnlId int,TxnId int,RowNum int,  TxnDate date)
INSERT @t values
(5, 10001,65, '2015-01-01'),
(2, 10001,66, '2015-01-02'),
(2, 10001,66, '2015-01-03'),
(2, 10001,66, '2015-01-04'),
(2, 10001,67, '2015-01-04'),
(2, 10001,67, '2015-01-04'),
(10,10002,11, '2015-01-03'),
(8, 10002,12, '2015-01-04'),
(5, 10003,15, '2015-01-05'),
(98,10003,16, '2015-01-06')

查询:

;WITH CTE AS
(
  SELECT 
    DENSE_RANK() over(partition by txnID order by TxnDate desc) rn,
    JnlId,  TxnId,  RowNum, TxnDate
  FROM @t
)
SELECT JnlId,  TxnId,  RowNum, TxnDate FROM CTE
WHERE rn<=2

结果:

JnlId  TxnId  RowNum  TxnDate
2      10001  66      2015-01-04
2      10001  67      2015-01-04
2      10001  67      2015-01-04
2      10001  66      2015-01-03
8      10002  12      2015-01-04
10     10002  11      2015-01-03
98     10003  16      2015-01-06
5      10003  15      2015-01-05