select 来自 table 的记录基于行比较逻辑但使用集合操作

select records from a table based on row comparison logic but using set operation

我知道这个问题听起来有点奇怪,但这是真的

我有一个 table 没有唯一字段的 [Id,PType,TNo]。以下是数据集:

insert into test.dbo.test_tsac values 
(1, 'tf' ,  2 ),
(2, 'pg' ,  3 ),
(3, 'tf' ,  1 ),
(3, 'pg' ,  1 ),
(4, 'tf' ,  5 ),
(4, 'LL' ,  2 ),
(4, 'pg' ,  1 ),
(5, 'pg' ,  2 ),
(5, 'pg' ,  4 )

要求如下:

1.For 一个Id,如果只有一条记录保留在结果集中(例如

(1, 'tf' ,  2 ),
(2, 'pg' ,  3 )

2.for 如果记录多于

则为 id

我们将选择 4,'LL',2 因为 4,pg,1 被丢弃,我们需要从剩余中进行升序排序。

所以上述数据集的输出将是:

(1, 'tf' ,  2 ),
(2, 'pg' ,  3 ),
(3, 'tf' ,  1 ),
\\\\\\\\
\\\\\\\\
(4, 'LL' ,  2 ),
\\\\\\\\
(5, 'pg' ,  2 ),
\\\\\\\\

我非常感谢这个很棒的社区提供的所有帮助,我不希望这里有一个完整的 executable 查询。任何 idea/approach/suggestion 都有很大帮助

请注意,我将需要 运行 在非常大的数据集 (~1M) 上执行此操作,因此我认为使用 Cursor 是不可取的,因此在设置操作上请求一些东西 basis.But如果 cursor/loops 是最后的选择,我也会这样做

我尝试过自连接,根据 Ptype 分离 tables 然后重新编译它们...分组也没有帮助。

使用 CTEROW_NUMBER(),有条件 ORDER BY

declare @test table (Id int, PType char(2), TNo int)
insert into @test
values
(1, 'tf' ,  2 ),
(2, 'pg' ,  3 ),
(3, 'tf' ,  1 ),
(3, 'pg' ,  1 ),
(4, 'tf' ,  5 ),
(4, 'LL' ,  2 ),
(4, 'pg' ,  1 ),
(5, 'pg' ,  2 ),
(5, 'pg' ,  4 )

;with cte as(
    select *,
    RN = row_number() over (partition by Id order by case when PType = 'tf' then 1 end, PType, TNo)
    from @test)

select
    Id
    ,PType
    ,TNo
from 
    cte
where RN = 1