2012-06-19 34 views
6

Tôi không biết liệu điều tôi đang hỏi có thể xảy ra hay không, nhưng đây là tình huống của tôi. Tôi có một bảng được cấu trúc giống như thế này:Làm thế nào để viết một truy vấn MYSQL mà sẽ trả lại trẻ em lồng nhau dưới cha mẹ?

+--------------------------------------------------+ 
| id | parent_id | name | category | .... 
+--------------------------------------------------+ 
| 0 |  -1  | item0 |  1  | 
| 1 |  0  | item1 |  1  | 
| 2 |  0  | item2 |  1  | 
| 3 |  2  | item3 |  1  | 
| 4 |  2  | item4 |  1  | 
| 5 |  -1  | item5 |  1  | 
+--------------------------------------------------+ 

Một parent_id -1 sẽ có nghĩa là mục "cơ sở" không có cha mẹ. Mỗi mục sẽ có nhiều cột thông tin hơn. Tôi cần phải bằng cách nào đó đầu ra tất cả các mục trong một thể loại lồng như sau:

item0 => item1  
     => item2 
      => item3 
      => item4 
item5 

Tôi không biết nếu điều đó có ý nghĩa hay không, nhưng hy vọng nó! Cách duy nhất tôi có thể nghĩ đến việc thực hiện điều này là tạo truy vấn để nhận tất cả các mục "cơ sở" (truy vấn các hàng có parent_id = -1) sau đó lặp qua từng hàng kết quả, truy vấn các hàng có parent_id của chúng. bằng id của hàng hiện tại, sau đó lặp lại quá trình đi sâu hơn và sâu hơn cho đến khi không có thêm con nào cho một mục cơ sở.

Có cách nào tốt hơn không?

Cảm ơn !!

+8

tôi sẽ đi cho 'null' để chỉ ra không có cha mẹ –

+3

Điều đó nghe như một ý tưởng hay. Tôi không thực sự biết những gì tôi đang làm ;-) – Nate

+0

Bạn có thể nhận được tất cả trong một đi và sau đó xây dựng cấu trúc trong php: http://stackoverflow.com/questions/2915748/how-can-i-convert- a-series-of-cha-con-mối quan hệ-thành-một-thứ bậc-tre – jeroen

Trả lời

9

Không thể thực hiện trong SQL thuần túy.

SQL được thiết kế để làm việc với dữ liệu quan hệ không phải là cây (dữ liệu phân cấp).

Bạn có thể đại diện cho cây trong lược đồ SQL, tuy nhiên bạn sẽ không thể tạo ra một cây như bạn định làm.

Cách duy nhất để làm là nhận được kết quả có thể sử dụng bằng cách thực hiện nhiều lần tham gia ở cấp bạn đang lưu trữ.

Giản đồ hiện tại của bạn có thể hỗ trợ nhiều cấp, tuy nhiên, sẽ rất khó quản lý nhiều hơn một hoặc hai cấp.

Bạn có thể quan tâm đến Nested Set Model hoặc Managing hierarchical data in mysql

Có một số thực hiện Nested Set như this one để làm việc với Học thuyết 2

+0

+1 Hãy đánh bại tôi. Đây là một bản sao của liên kết thứ hai (http://www.vbmysql.com/articles/database-design/managing-hierarchical-data-in-mysql) với định dạng tốt hơn. Chúc mừng! –

+0

@XavierHolt, cảm ơn tôi đã cập nhật liên kết. Tôi đã thực sự tìm kiếm các bài gốc trên dev mysql nhưng không thể tìm thấy nó trở lại. –

1

này là không thể trong SQL tinh khiết và nó là một trong những khía cạnh của mô hình quan hệ tạo ra nhiều chỉ trích nhất.

tôi sẽ khuyên bạn nên đọc các liên kết về bài đăng này: SQL "tree-like" query - most parent group

Và cũng có thể, nếu ứng dụng của bạn dựa quá nhiều về vấn đề này, tôi sẽ đề nghị bạn để có một cái nhìn tại một số cơ sở dữ liệu không quan hệ có thể đại diện loại dữ liệu này tốt hơn, chẳng hạn như MongoDB (www.mongodb.org)

1

Tôi hy vọng tôi hiểu rõ câu hỏi của bạn (nó khá muộn ở đây và tôi vừa đến từ một quán bar), nếu tôi không, chỉ cần chính xác tôi và tôi sẽ viết lại câu trả lời của tôi.

Từ kịch bản được đưa ra, tôi đoán có một bảng cha khác, không có ở đó?

Cho phép hình dung thuộc tính của nó là id và tên. Bảng trẻ em là một trong những do bạn (w/o thuộc tính không cần thiết).

mysql> insert into parent(name) values ('petr'),('tomas'),('richard'); 


mysql> insert into children(name,parent_id) values('michal',1),('tomas',1),('michal'); 


mysql> select parent.id,parent.name,children.name from parent left join children on parent.id = children.parent_id; 

+----+---------+--------+ 
| id | name | name | 
+----+---------+--------+ 
| 1 | petr | michal | 
| 1 | petr | tomas | 
| 2 | tomas | NULL | 
| 3 | richard | michal | 
+----+---------+--------+ 

Để thực hiện việc này nhiều lần (cha mẹ có con có con đã nhận con, v.v.) Bạn có thể thực hiện điều đó bằng cách sử dụng nhiều phép nối.

mysql> select parent.id,parent.name as Parent,children.name as Child,children2.name as Child2 from parent left join children on parent.id = children.parent_id left join children2 on children.id = children2.parent_id; 
+----+---------+--------+--------+ 
| id | Parent | Child | Child2 | 
+----+---------+--------+--------+ 
| 1 | petr | michal | NULL | 
| 1 | petr | tomas | dan | 
| 1 | petr | tomas | pavel | 
| 2 | tomas | NULL | NULL | 
| 3 | richard | michal | michal | 
+----+---------+--------+--------+ 

Nếu tôi hoặc didnt trả lời những gì bạn yêu cầu hoặc bạn cần giải thích thêm cho tôi biết;]

Kính trọng,

Releis

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