2012-10-29 55 views
3

我正在使用SQL Server 2008 R2。 我有以下數據:根據列值,行必須在結果集中顯示相同順序

ID Value OrderNumber 
1  A   NULL 
2  E   4 
3  C   NULL 
4  B   NULL 
5  F   2 
6  D   NULL 

我想寫必須由訂單編號列在考慮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 

感謝您的閱讀和答案。

+0

什麼順序記錄是,如果他們有'NULL'的訂單編號? –

+0

該記錄必須按ID列升序進行排序。 – bselvan

+0

如果兩條記錄都說'位置2'會發生什麼?講座中討論的主題是什麼?類中涵蓋了SQL Server 2008 SQL的哪些功能? –

回答

3

我已經嘗試了多種不同的方式,但我能找到的唯一途徑,在保證方式產生所需的結果是:

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,並將這些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 
+0

這工作。非常感謝你@Damien_The_Unbeliever。 – bselvan

+0

對於這個問題太複雜 –

0

試試這個:

SELECT * 
FROM  tableName 
Order BY CASE WHEN OrderNumber IS NULL THEN ID ELSE OrderNumber END 
+0

從樣本集中,'ID' 4和'OrderNumber' 4對於'CASE'表達式具有相同的值,因此可以按任一順序出現。 –

+0

這沒有奏效。第4號訂單顯示爲第五行。 – bselvan

1

找到比接受的答案一個更好的解決方案:

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 
+0

如果我將ID 2s'OrderNumber'更改爲3(從4開始),那麼ID 2和5都被賦值爲2的rn1值 - 因此不能保證它們之間的輸出順序。 –

+0

@Damien_The_Unbeliever很好的被發現,它已被修正 –

+0

也能正常工作。我可以理解達米安的解決方案。但我還沒有想出你的解決方案。所以我更喜歡達米安的解決方案作爲接受的答案。感謝您的回答。 – bselvan

相關問題