2011-06-08 72 views
3

我試圖實現一個類別表。 簡化表描述就像是假設這在其父元素之後排序子元素

id -- name -- parent_id 

的樣本數據,如

id - name - parent_id 
1 test1 null 
2 test2 null 
3 test3 null 
4 test4 1 
5 test5 4 
6 test6 2 
7 test7 1 

我掙扎拿出一個SQL查詢,將返回按以下順序設置記錄

id - name - parent_id 
1 test1 null 
4 test4 1 
5 test5 4 
7 test7 1 
2 test2 null 
6 test6 2 
3 test3 null 

基本上,子元素在其父元素之後返回。

-----------------------解決方法1:在代碼中使用LINQ /遞歸-------------- -----------

不完全是一個SQL解決方案,但最終它的工作原理。

+2

我不認爲有足夠的規格。這似乎是任意的,爲什麼'test1'是'test2'或'test3'之前的父對象。 – 2011-06-08 23:36:48

+2

我可能會錯過這一點。但是我看不到樣本數據與預期數據順序之間的關係。 (這是遲到了,所以如果我錯過了顯而易見的道歉) – lethalMango 2011-06-08 23:37:20

+0

test1應該在測試之前4是他希望根據父親關係排序,因此test2是有序列表中的下一個ID將是下一個父親在結果 – Trey 2011-06-08 23:38:19

回答

2

根據您試圖對查詢進行的操作,您無需對其進行排序。你只需要確保首先創建父母。因此,運行您的查詢按父ID排序,將結果放入一個數組並循環訪問該數組。在每次迭代時,都要進行檢查以確保父代存在,如果它有父代。如果父母不存在,只需將該項目移動到數組的末尾,然後進入下一個,那麼最後只能看到一些移動的案例,因此它仍然非常有效。

1

我過去一直在做的事情是把數據庫分成以下幾部分(儘管我可能還有其他一些解決方案,但我並不是最好的)。

categories 
- category_id | int(11) | Primary Key/Auto_Increment 
.. 
.. 

sub_categories 
- sub_category_id | int(11) | Primary Key/Auto_Increment 
- category_id  | int(11) | Foreign Key to categories table 
.. 
.. 
1

通過以下作品中的查詢增加了一個額外order_parent列中包含的任何父ID或該行的ID,這取決於它是否是父。然後,它主要根據order_parent ID對它們進行分組,然後通過parent_idnull(實際父母)進行排序。

兩件事情:

  1. 這又多了一個,你本來想列,因此就忽視它。
  2. 如果您的數據庫最後返回parent_id的nulls,請添加DESC

好的問題,順便說一下!

SELECT id, 
     name, 
     parent_id, 
     (
      case 
      when parent_id is null then id 
      else parent_id 
      end 
     ) AS order_parent 
FROM  myTable 
ORDER BY order_parent, parent_id 
+0

你運行這個查詢嗎?它排序的孩子,但孫子(id = 5)最後結束 – Bohemian 2011-06-09 00:04:37

+0

啊,孫子。相當。我沒有注意到這些。 – 2011-06-09 00:09:16

+0

你試圖運行它。它看起來即將工作。但實際上並沒有工作。爲了簡單起見(爲了避免空值),我將ID複製到沒有父節點的節點的父節點字段中。 – robert 2011-06-09 00:09:51

1

這裏是我會做什麼:

SELECT id, name, parent_id, (CASE WHEN COALESCE(parentid,0)=0 THEN id ELSE (parentid + '.' + id)) as orderid 
FROM table 
ORDER BY (CASE WHEN COALESCE(parentid,0)=0 THEN id ELSE (parentid + '.' + id)) 

這應該創建一個新列名爲訂單ID具有的parentid點的ID(1.4,4.5,等)列在父id爲null,它會放上id。這樣你會得到的訂單爲1,1.4,4,4.5等。

請檢查代碼,因爲我沒有測試就這麼寫。它應該接近。