我尝试了许多不同的方法,但我能找到的唯一能保证产生所需结果的方法是:
declare @t table (ID int not null,Value char(1) not null,OrderNumber int null)
insert into @T(ID,Value,OrderNumber) values
(1,'A',NULL),
(2,'E',4),
(3,'C',NULL),
(4,'B',NULL),
(5,'F',2),
(6,'D',NULL)
;With Nbrs as (
select ROW_NUMBER() OVER (ORDER BY ID) as n from @t
), AvailableNbrs as (
select n,ROW_NUMBER() OVER (ORDER BY n) as rn from Nbrs where n not in (select OrderNumber from @t where OrderNumber is not null)
), RequiredOrders as (
select ID,ROW_NUMBER() OVER (ORDER BY ID) as rn from @t where OrderNumber is null
)
select
*,COALESCE(OrderNumber,an.n) as FinalOrder
from
@t t
left join
RequiredOrders ro
on
t.ID = ro.ID
left join
AvailableNbrs an
on
ro.rn = an.rn
order by COALESCE(OrderNumber,an.n)
我们使用一些 CTE 来查找OrderNumber
当前未分配的 s,并将那些 1-1 与没有 的行匹配OrderNumber
。
结果:
|--------- @t --------------| |----- RequiredOrders ---------| |----- AvailableNbrs -------------------| |- COALESCE -------|
ID Value OrderNumber ID rn n rn FinalOrder
----------- ----- ----------- ----------- -------------------- -------------------- -------------------- --------------------
1 A NULL 1 1 1 1 1
5 F 2 NULL NULL NULL NULL 2
3 C NULL 3 2 3 2 3
2 E 4 NULL NULL NULL NULL 4
4 B NULL 4 3 5 3 5
6 D NULL 6 4 6 4 6