2011-11-05 23 views
10

Tôi đang cố gắng để viết truy vấn SQL Server 2008 của tôi theo cách mà tôi chỉ có thể lặp qua đầu ra và đầu ra của tôi khi cần thiết. Tôi đã thực hiện công cụ này một cách sai lầm nhiều lần và Coldfusion làm công việc khó khăn trong trang, nhưng cần điều này được thực hiện trong SQL Server.Tôi làm cách nào để đặt hàng bởi cha mẹ và con?

FeatureID ParentID Feature 
-------------------------- 
1   0  Apple  
2   0  Boy 
3   2  Charles 
4   1  Daddy 
5   2  Envelope 
6   1  Frankfurter 

Tôi muốn resultset truy vấn của tôi trông như thế này:

FeatureID ParentID Feature 
-------------------------- 
1   0  Apple  
4   1  Daddy 
6   1  Frankfurter 
2   0  Boy 
3   2  Charles 
5   2  Envelope 

Nếu ParentID là 0, nó có nghĩa rằng đó là một loại lớn. Nếu ParentID lớn hơn 0, nó có nghĩa là nó là một thể loại nhỏ, một con của cha/mẹ.

Vì vậy, cha mẹ cần phải được đặt hàng A - Z và trẻ em cần phải được đặt hàng A-Z.

Bạn có thể giúp tôi đặt hàng này đúng cách không?

SELECT FeatureID, ParentID, Feature 
FROM Features 
ORDER BY 
+0

Vậy tại sao là Boy với ParentID 0 được sắp xếp dưới Frankfurter với ParentID 1? – Andomar

+0

Bởi vì tôi muốn xuất ra phụ huynh và sau đó là con của nó và sau đó là cha mẹ kế tiếp và sau đó là con của nó. –

+1

hãy thử cách này đơn giản hơn nhiều: http://stackoverflow.com/questions/13382380/mysql-order-by-parent-and-child – Otak

Trả lời

9

Từ nhận xét của bạn, nếu bạn biết chỉ có hai cấp độ, có một cách dễ dàng giải pháp:

select * 
from @Features feat 
order by 
     case 
     when ParentID = 0 
     then Feature 
     else (
       select Feature 
       from @Features parent 
       where parent.FeatureID = feat.ParentID 
       ) 
     end 
,  case when ParentID = 0 then 1 end desc 
,  Feature 
  1. Sắp xếp theo tên của phần tử gốc: cho thư mục gốc, đây là cột tính năng. Đối với trẻ em, tra cứu tên của root bằng truy vấn phụ.
  2. Sắp xếp các thư mục gốc trên đỉnh
  3. Sắp xếp những đứa trẻ theo tên

Example at SE Data.

+0

Jeepers !!! Đó là rất nhiều mã cho một cái gì đó mà có vẻ như nó phải là một LOT đơn giản hơn. Ví dụ của bạn dường như hoạt động tốt. Điều này cồng kềnh hơn là làm theo cách khác. –

+0

Vâng, cách phức tạp cho mã sản xuất. Tôi đã hy vọng một người khác sẽ đăng một giải pháp đơn giản hơn. Lưu ý rằng bạn có thể đơn giản hóa rất nhiều mã nếu bạn bị giới hạn ở độ sâu nhất định, hãy nói tối đa 2 nút giữa gốc và lá – Andomar

+0

Thực ra, sẽ chỉ có hai cấp độ, cấp độ gốc và con. Ther sẽ không phải là ông bà hoặc cháu. –

6

cho mysql, bạn có thể thử: (với điều kiện ParentID của trẻ em của bạn là FEATUREID của ParentID của bạn)

SELECT FeatureID, ParentID, Feature 
FROM Features 
ORDER BY case when ParentID=0 then FeatureID else ParentID end * 1000 + FeatureID ASC 
+0

+1 Điều này hoạt động độc đáo miễn là bảng theo thứ tự alfabetical, và bạn không có nhiều hơn 999 hàng – Andomar

+1

Không nên đây chỉ là 'ORDER BY CASE WHEN ParentID = 0 THEN FeatureID ELSE ParentID END ASC, FeatureID ASC 'thay vào đó? Bởi vì sau đó nó sẽ vẫn sử dụng các chỉ mục và nó cũng sẽ không bị giới hạn tới 999 bản ghi. Nhưng có điều này không thành công nếu bạn có '(7, 8, 'bar')' và '(8, 0, 'foo')', ('SELECT COUNT (1) TỪ tính năng WHERE FeatureID Seph

Các vấn đề liên quan