2013-04-23 23 views
7

Nói rằng tôi có một bảng như thế này:Chánh con mysql

================================= 
| ID | Parent_ID | Page_Name | 
================================= 
| 1 | NULL  | Home  | 
| 2 | NULL  | Services | 
| 3 | 2   | Baking  | 
| 4 | 3   | Cakes  | 
| 5 | 3   | Bread  | 
| 6 | 5   | Flat Bread | 
--------------------------------- 

Làm thế nào tôi có thể đi về thực sự ra lệnh cho các kết quả trong định dạng này? I E. Đặt hàng bởi Cha mẹ -> Trẻ em -> Trẻ con, trên cơ sở tôi sẽ chỉ yêu cầu nói tối đa 5 cấp độ? Tôi đã xem xét "Mô hình tập hợp lồng nhau" nhưng có vẻ như quá phức tạp đối với các yêu cầu của tôi. Những gì tôi không chắc chắn là thực sự hiểu một truy vấn SQL tôi có thể sử dụng để hiển thị kết quả của tôi như trên, hoặc trong tình huống này tôi nên sử dụng một ngôn ngữ phía máy chủ như PHP để làm điều này cho tôi?

+0

Không chắc chắn nếu đây là ý của bạn, nhưng tôi nghĩ điều này sẽ giúp: http://stackoverflow.com/questions/6240028/select-parent-and-children-with-mysql – We0

+2

Bạn đang nói về đệ quy liệt kê một cây theo thứ tự id? MySQL không hỗ trợ điều đó, cuối cùng tôi đã kiểm tra. PostgreSQL, Oracle và SQL Server đã thực hiện thông qua CTE đệ quy. Cách duy nhất tôi biết làm thế nào để làm điều đó với mysql là thực hiện nhiều cuộc gọi đến cơ sở dữ liệu thông qua khách hàng của bạn, tham khảo tập kết quả cuối cùng. –

+0

@ We0 Điều này chỉ giải quyết 2 cấp độ (phụ huynh và trẻ em trực tiếp) –

Trả lời

1

Bạn có thể thử này:

select t.*, 
     (case when t4.parent_id is not NULL then 5 
      when t4.id is not null then 4 
      when t3.id is not null then 3 
      when t2.id is not null then 2 
      when t1.id is not null then 1 
      else 0 
     end) as level 
from t left outer join 
    t t1 
    on t.parent_id = t1.id left outer join 
    t t2 
    on t1.parent_id = t2.id left outer join 
    t t3 
    on t2.parent_id = t3.id left outer join 
    t t4 
    on t3.parent_id = t4.id 
order by coalesce(t4.parent_id, t4.id, t3.id, t2.id, t1.id, t.id), 
     coalesce(t4.id, t3.id, t2.id, t1.id, t.id), 
     coalesce(t3.id, t2.id, t1.id, t.id), 
     coalesce(t1.id, t.id), 
     t.id 

truy vấn đệ quy không cần thiết nếu hệ thống phân cấp là hữu hạn.

Thứ tự theo mệnh đề là phần phức tạp. Nó chỉ đơn đặt hàng theo cấp độ của hệ thống phân cấp, bắt đầu từ cấp cao nhất.

Phiên bản gốc của điều này đã làm việc trên dữ liệu trong câu hỏi. Thử nghiệm rộng rãi hơn cho thấy rằng nó không phải lúc nào cũng hoạt động. Tôi tin rằng phiên bản này luôn hoạt động.

+0

Làm cách nào tôi có thể tích hợp cấp độ này? –

4

EDIT

làm việc mẫu giải quyết Gordons lưu ý

đường nút Query tính toán như bạn đã cố định độ sâu cây tối đa, và trật tự của nó.

SQL Fiddle

MySQL 5.5.30 Schema Cài đặt:

create table mytable(id int, parent_id int, name varchar(100)); 

insert mytable(id, parent_id, name) 
values (1, null, 'Home'), 
(2, null, 'Services'), 
(3, 2, 'Baking'), 
(4, 3, 'Cakes'), 
(5, 3, 'Bread'), 
(6, 5, 'Flat Bread'), 
(7, 1, 'Something'); 

Query 1:

select t0.*, 
    concat(
     case coalesce(t4.Parent_ID, 0) 
     when 0 then '' 
     else concat(cast(t4.Parent_ID as char), '\\') 
     end, 
     case coalesce(t3.Parent_ID, 0) 
     when 0 then '' 
     else concat(cast(t3.Parent_ID as char), '\\') 
     end, 
     case coalesce(t2.Parent_ID, 0) 
     when 0 then '' 
     else concat(cast(t2.Parent_ID as char), '\\') 
     end, 
     case coalesce(t1.Parent_ID, 0) 
     when 0 then '' 
     else concat(cast(t1.Parent_ID as char), '\\') 
     end, 
     case coalesce(t0.Parent_ID, 0) 
     when 0 then '' 
     else concat(cast(t0.Parent_ID as char), '\\') 
     end, 
     cast(t0.id as char) 
    ) as path 
from mytable t0 
    left join mytable t1 on t0.Parent_ID = t1.Id 
    left join mytable t2 on t1.Parent_ID = t2.Id 
    left join mytable t3 on t2.Parent_ID = t3.Id 
    left join mytable t4 on t3.Parent_ID = t4.Id 
order by 
    concat(
     case coalesce(t4.Parent_ID, 0) 
     when 0 then '' 
     else concat(cast(t4.Parent_ID as char), '\\') 
     end, 
     case coalesce(t3.Parent_ID, 0) 
     when 0 then '' 
     else concat(cast(t3.Parent_ID as char), '\\') 
     end, 
     case coalesce(t2.Parent_ID, 0) 
     when 0 then '' 
     else concat(cast(t2.Parent_ID as char), '\\') 
     end, 
     case coalesce(t1.Parent_ID, 0) 
     when 0 then '' 
     else concat(cast(t1.Parent_ID as char), '\\') 
     end, 
     case coalesce(t0.Parent_ID, 0) 
     when 0 then '' 
     else concat(cast(t0.Parent_ID as char), '\\') 
     end, 
     cast(t0.id as char) 
    ) 

Results:

| ID | PARENT_ID |  NAME | PATH | 
----------------------------------------- 
| 1 | (null) |  Home |  1 | 
| 7 |   1 | Something |  1\7 | 
| 2 | (null) | Services |  2 | 
| 3 |   2 |  Baking |  2\3 | 
| 4 |   3 |  Cakes | 2\3\4 | 
| 5 |   3 |  Bread | 2\3\5 | 
| 6 |   5 | Flat Bread | 2\3\5\6 | 
+0

Đơn đặt hàng của bạn theo mệnh đề không hoạt động nếu bạn thêm "(7, 1)" vào tập dữ liệu. –

+0

@GordonLinoff, vâng, cố định với một số câu trả lời của bạn) – shibormot

+0

Cảm ơn bạn đã trả lời. Nó nằm ngoài phạm vi của những gì tôi hiểu trong mysql. Bạn có thể giải thích một thời gian ngắn như thế nào công trình này tôi thực sự muốn hiểu nó hơn là chỉ sao chép và dán. –

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