2017-03-07 31 views
2

我有一個數據集,其中有一個行數列表,每列都有一個ID,顯示order和一個可爲空的parentID。如果他們有一個,我需要將他們按遞增的顯示順序歸還給父母。我不知道如何去做這件事。我正在考慮嘗試一些工會,但他們需要一些不受限制的工會。按顯示順序和父代號排序

ID order parentID 
4 1 
6 2 
5 1  6 
1 2  6 
7 3  6 
77 3 
89 1  77 
43 4 
23 5 
2 1  23 
3 2  23 

回答

1

你必須構建佔級別之間的排序,以及每個級別中的排序排序機制。我會告訴你如何使用遞歸CTE來做到這一點。

首先,您需要確定可以比較多少個元素。在你的表格中,答案是5,但這可能是任意的。因此,我們將查詢首先

declare @dyn_ord as int = (select len(MAX(ordering)) from #A) 

這得到的數字的數量,在這種情況下就是這裏,我使用「#A」作爲你的表的名稱。

接下來,我們建立了遞歸CTE與領域,我們希望

declare @dyn_ord as int = (select len(MAX(ordering)) from #A) 

; with 
    Parent as (
    -- Anchor member definition 
     select a.Id -- of course show the ID 
       , a.parentID -- show the parent's ID 
       , cast(a.ID as varchar(max)) as Path -- this is bonus to help understand recursion 
       , CAST((REPLACE(STR(ordering,@dyn_ord),' ','0')) AS nvarchar(max)) AS OrderString -- our modified ordering, explanation to follow 
      from #A a 
      where a.parentId is null 
     union all 
    -- Recursive member definition 
     select c.Id 
       , c.parentID 
       , cast(Path + ' -> ' + cast(c.ID as varchar(max)) as varchar(max)) as Path 
       , (p.OrderString + '.' + CAST((REPLACE(STR(c.ordering,@dyn_ord),' ','0')) AS nvarchar(max))) AS OrderString 
      from #A as c 
      inner join Parent as p 
       on c.parentID = p.ID 
    ) 
SELECT Id 
     , parentID 
     , Path 
     , OrderString 
    FROM Parent 
    order by OrderString asc 

OrderString是我們用來秩序的機制。在給定的級別中,它(1)採用排序,(2)將其轉換爲字符串,並且(3)根據需要填充任何額外的零。如果你想比較像1和10這樣的排序,需要第三步,這並不總是給你想要的字符串比較。 (2)添加一個句點(不需要但有助於理解排序),(3)然後執行相同的操作如前段所述的三個步驟。

+0

聖潔的廢話。我有很多需要學習的東西,非常感謝! –

+0

不客氣:)爲了更好地感受一下發生了什麼,玩一下這一點。 – KindaTechy

0

只要把所有你想要在你的ORDER BY子句來排序的列:

select parentID, ordering, ID 
from mytab 
order by parentID, ordering 

(我已經改名爲order訂購,因爲order是一個SQL關鍵字)

UPDATE

要將NULL parentID移動到底部,可以使用NULLS LAST如果您的RDBMS支持它:

select parentID, ordering, ID 
from mytab 
order by parentID nulls last, ordering 
+0

這樣做只是把所有的行都放在最上面的空父母上,而所有的父母都放在最下面的一個非空父母 –

+0

@DanWier在你的問題中,你沒有提到你想要的NULL值。無論如何,請參閱我的更新答案,瞭解可能有效的方法(如果這樣做不起作用,則應編輯您的問題並使用適當的RDBMS標記以獲得更具體的答案)。 –