2010-09-14 44 views
7

Tôi có bảng phù thủy chứa các trường: id, parent_id, name (v.v ..)Chọn các hàng từ bảng theo thứ tự cây

tôi muốn đặt bảng này trong "thứ tự du lịch cây".

id parent_id 
1, 0 
3, 1 
5, 1 

2, 0 
8, 2 

4, 0 
9, 4 

(...)

trong ngắn mô tả: lấy nút gốc, thêm tất cả trẻ em, mất nút gốc tới thêm trẻ em, vv

Trả lời

10

Bằng cách mô tả của bạn tôi giả sử bạn có nghĩa là breadth- đặt hàng đầu tiên, có thể được thực hiện bằng easly một vỚI truy vấn đệ quy (PostgreSQL 8.4+):

WITH RECURSIVE tree 
AS 
(
    SELECT 
     node_name, id, parent_id, NULL::varchar AS parent_name 
    FROM foo 
    WHERE parent_id IS NULL 
    UNION 
    SELECT 
     node_name, f1.id, f1.parent_id, tree.node_name AS parent_name 
    FROM 
     tree 
     JOIN foo f1 ON f1.parent_id = tree.id 
) 
SELECT node_name, empno, parent_id, node_name FROM tree; 

Bạn cũng có thể sử dụng để sâu-đầu tiên sử dụng sau SQL:

WITH RECURSIVE tree 
AS 
(
    SELECT 
     node_name, id, parent_id, NULL::varchar AS parent_name, id::text AS path 
    FROM foo WHERE parent_id IS NULL 
    UNION 
    SELECT 
     node_name, f1.id, f1.parent_id, tree.node_name AS parent_name, tree.path || '-' || f1.id::text AS path 
    FROM 
     tree 
     JOIN foo f1 ON f1.parent_id = tree.id 
) 
SELECT node_name, empno, parent_id, node_name, path FROM tree ORDER BY path; 
+0

Thx cho điều đó, tôi đã không nhận thức được các truy vấn WITH hiện tại trong Postgres – canni

+0

Tôi nghĩ rằng chúng tôi không thể sử dụng câu lệnh UNION trong mệnh đề WITH – Fer

+1

Giải pháp của bạn cho thứ tự độ sâu đầu tiên sẽ không hoạt động đối với id với số chữ số khác nhau. – synergetic

-2
SELECT * FROM table ORDER BY id,parent_id 

Điều đó sẽ đặt cột của tôi trong lệnh đặt trong truy vấn.

Trừ khi bạn có ý nghĩa GROUP các mục, phù thủy Tôi nghĩ rằng bạn, sau đó sử dụng

SELECT * FROM table ORDER BY id GROUP BY parent_id 

Và tôi cũng khuyên bạn nên đọc bài viết này: http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/

+0

Điều đó sẽ không tạo ra kết quả theo thứ tự tôi muốn ... – canni

+0

này sẽ tạo ra lỗi cú pháp trong Postgres (trường id phải được sử dụng trong chức năng tổng hợp), đây không phải là MySQL :) – canni

+0

Ahh ok, xin lỗi, tôi nghĩ rằng sẽ có làm việc dưới 'postgres', im không tốt với nó. – RobertPitt

0

Bạn cũng có thể sử dụng các mô-đun LTree tuyệt vời, nhưng bạn cần phải sắp xếp lại dữ liệu của bạn một chút.

4

Như chú ý của synergetic, giải pháp cho đơn đặt hàng sâu-đầu tiên được cung cấp bởi Diogo Biazus sẽ không làm việc cho id với số khác nhau của chữ số.

Nhưng bạn có thể sử dụng giải pháp này để thay thế, sử dụng mảng các số nguyên:

WITH RECURSIVE tree 
AS 
(
    SELECT 
     node_name, id, parent_id, NULL::varchar AS parent_name, array[id] AS path 
    FROM foo WHERE parent_id IS NULL 
    UNION 
    SELECT 
     node_name, f1.id, f1.parent_id, tree.node_name AS parent_name, tree.path || f1.id AS path 
    FROM 
     tree 
     JOIN foo f1 ON f1.parent_id = tree.id 
) 
SELECT node_name, empno, parent_id, node_name, path FROM tree ORDER BY path; 
Các vấn đề liên quan