根据重复的组值获取数据

时间:2020-06-12 15:48:18

标签: sql-server window-functions sql-server-2017

我不知道如何正确地命名问题,但这是示例数据:



CREATE TABLE dbo.test_data
(
    row_version     VARBINARY(8)
  , account_number  CHAR(8)
  , account_balance DECIMAL(10, 2)
  , group_rank      BIGINT
  , rownum          BIGINT
);

INSERT INTO dbo.test_data
VALUES (0x000000000013fd24, '46436663', 123.00, 4, 86)
     , (0x000000000013fd23, '46436663', 123.00, 4, 86)
     , (0x000000000013fd22, '46436663', 123.00, 4, 85)
     , (0x000000000013fd21, '46436663', 123.00, 4, 85)
     , (0x000000000013fd20, '46436663', 123.00, 4, 83)
     , (0x000000000013fd1f, '46436663', 555.00, 2, 83)
     , (0x000000000013fd21, '46436663', 123.00, 4, 85)
     , (0x000000000013fd20, '46436663', 123.00, 4, 83)
     , (0x000000000013fd21, '46436663', 123.00, 4, 85)
     , (0x000000000013fd20, '46436663', 123.00, 4, 83)
     , (0x000000000013fd1e, '46436664', 12345.00, 5, 82)
     , (0x000000000013fd1d, '46436664', 12345.00, 5, 82)
     , (0x000000000013fd1c, '46436664', 12345.00, 5, 82)
     , (0x000000000013fd1b, '46436664', 12345.00, 5, 81)
     , (0x000000000013fd1a, '46436664', 12345.00, 5, 81)
     , (0x000000000013fd19, '46436664', 12345.00, 5, 78)
     , (0x000000000013fcb3, '46436664', 123.00, 6, 77)
     , (0x000000000013fcb2, '46436664', 123.00, 6, 77)
     , (0x000000000013fcb1, '46436664', 123.00, 6, 76)
     , (0x000000000013fcb0, '46436664', 123.00, 6, 76);

这是数据的样子:

SELECT * FROM dbo.test_data
ORDER BY row_version DESC

enter image description here

这里1和4(蓝色)是连续的组号,在您按row_version订购它们时,它们的最小顺序为2个相同的值。我需要先找到不同的group_rank(2,红色),然后检查rownum值(3,6,紫色),其中上一组(蓝色)和{ {1}}用于该组结束之前的记录(红色)。如果这些值相差1,那么我需要返回MIN(row_num),然后返回它,否则-我不需要返回它。

我对帐户低于2点和5点(红色)时发生的情况不感兴趣。

因此,通过查看该数据,应该返回唯一的帐户-row_num的{​​{1}}值与account_number相同(83)。

1 个答案:

答案 0 :(得分:0)

有趣的问题,我想第一步是找到问题account_numbers,您可以这样做。

select 
    * 
from 
    dbo.test_data t1
cross apply (
    select top 1 
        * 
    from 
        dbo.test_data 
    where 
        account_number = t1.account_number
        and rownum = t1.rownum
        and row_version > t1.row_version 
    order by 
        row_version asc) t2
where 
    t1.group_rank <> t2.group_rank 
order by
    t1.row_version;

enter image description here

那你就可以做到

select distinct 
    t0.account_number 
from 
    test_data t0

except

select distinct
    t1.account_number 
from 
    dbo.test_data t1
cross apply (
    select top 1 
        * 
    from 
        dbo.test_data 
    where 
        account_number = t1.account_number
        and rownum = t1.rownum
        and row_version > t1.row_version 
    order by 
        row_version asc) t2
where 
    t1.group_rank <> t2.group_rank