Sql 根据列值,该行在结果集中的显示顺序必须相同
我正在使用SQLServer2008R2。 我有以下数据:Sql 根据列值,该行在结果集中的显示顺序必须相同,sql,sql-server-2008-r2,Sql,Sql Server 2008 R2,我正在使用SQLServer2008R2。 我有以下数据: ID Value OrderNumber 1 A NULL 2 E 4 3 C NULL 4 B NULL 5 F 2 6 D NULL 我想编写一个查询,该查询必须根据OrderNumber列获取数据排序,并考虑OrderNumber值。查询结果必须如下所示: ID
ID Value OrderNumber
1 A NULL
2 E 4
3 C NULL
4 B NULL
5 F 2
6 D NULL
我想编写一个查询,该查询必须根据OrderNumber列获取数据排序,并考虑OrderNumber值。查询结果必须如下所示:
ID Value OrderNumber
1 A NULL
5 F 2 --indicates row must be second in result set.
3 C NULL
2 E 4 --indicates row must be fourth in result set.
4 B NULL
6 D NULL
感谢您的阅读和回答。试试这个:
SELECT *
FROM tableName
Order BY CASE WHEN OrderNumber IS NULL THEN ID ELSE OrderNumber END
我尝试了许多不同的方法,但我能找到的唯一能保证产生所需结果的方法是:
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
找到了比公认答案更好的解决方案:
declare @t table(id int, value char, ordernumber int)
insert @t values(1,'A', null)
insert @t values(2,'E',4)
insert @t values(3,'C',NULL)
insert @t values(4,'B',NULL)
insert @t values(5,'F',2)
insert @t values(6,'D',NULL)
;with a as
(
select *, row_number() over (order by id)+.1 rn1 from @t
where ordernumber is null
union all
select *, ordernumber - rank() over (order by ordernumber)+1 rn1 from @t
where ordernumber is not null
)
select * from a order by rn1, ordernumber
如果记录的OrderNumber为
NULL
,那么它们的顺序应该是什么?这些记录必须按ID列升序排列。如果两个记录都显示“位置2”,会发生什么情况?讲座讨论的主题是什么?SQL Server 2008 SQL的哪些功能包含在类中?@JonathanLeffler订单号值除空值外是唯一的。如果有20个结果,是否可以在样本集中的OrderNumber
上有35个值,ID
4和OrderNumber
4对于您的CASE
表达式将具有相同的值,因此可能以任意顺序出现。如果我将ID 2sOrderNumber
更改为3(从4),此问题就太复杂了,然后ID2和ID5都被分配了rn1
值2-因此不能保证它们之间的输出顺序。这同样有效。我能理解达米恩的解决方案。但是我还没有想出你的解决办法。所以我更喜欢达米恩的解决方案作为公认的答案。感谢您的回答。@t-clausen.dk我理解您的解决方案。但是我无法理解“ordernumber-rank()超过(按数字排序)+1”。如果你澄清一点,这对我有好处。@bselvan在本例中排名与row_number()完全相同。我使用rank的原因是,我从另一个解决方案开始,从未改变过它,因为它也是这样做的。我减去它来找到排名较低的ordernumber的数量,以找到顺序中的确切位置,当它们得到相同的值时,这是因为它们并排排列,而ordernumber决定了位置。感谢您的解释。我终于明白了这个疑问。这个解决方案相当聪明。再次感谢。