选择每个 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
我试图使用 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