Hàm đơn giản hơn
Trước hết, bạn có thể đơn giản hóa chức năng của bạn khá một chút. Hàm SQL đơn giản hơn này thực hiện tương tự:
CREATE OR REPLACE FUNCTION f_tree(_rev int)
RETURNS TABLE(id int, parent_id int, depth int) AS
$func$
WITH RECURSIVE tree_list AS (
SELECT t.id, t.parent_id, 1 -- AS depth
FROM tree t
WHERE t.id = $1
UNION ALL -- no point using UNION
SELECT t.id, t.parent_id, r.depth + 1
FROM tree_list r
JOIN tree t ON t.id = r.parent_id
)
SELECT t.id, t.parent_id, t.depth
FROM tree_list t
ORDER BY t.id;
$func$ LANGUAGE sql;
Gọi:
select * from f_tree(15);
-
Bạn có thể sử dụng plpgsql, có thể là hơi có lợi cho việc tính tiền mặt cho kế hoạch truy vấn trong các phiên bản trước PostgreSQL 9.2. Nhưng bạn đã vô hiệu hóa lợi ích lý thuyết duy nhất bằng cách sử dụng SQL động mà không cần. Điều này không có ý nghĩa gì cả. Đơn giản hóa thành SQL thuần túy.
-
Sử dụng
UNION ALL
thay vìUNION
, rẻ hơn vì không thể có sự giả mạo theo thiết kế.
Chỉ SQL
Rõ ràng, bạn có thể thay thế điều này bằng SQL thuần túy:
WITH RECURSIVE tree_list AS (
SELECT t.id, t.parent_id, 1 AS depth
FROM tree t
WHERE t.id = 15 -- enter parameter here
UNION ALL
SELECT t.id, t.parent_id, r.depth + 1
FROM tree_list r
JOIN tree t ON t.id = r.parent_id
)
SELECT t.id, t.parent_id, t.depth
FROM tree_list t
ORDER BY t.id;
Tương tự.
XEM
Bây giờ, VIEW
là một vấn đề tầm thường:
CREATE OR REPLACE VIEW v_tree15 AS
WITH RECURSIVE tree_list AS (
SELECT t.id, t.parent_id, 1 AS depth
FROM tree t
WHERE t.id <= 15 -- only detail to change
UNION ALL
SELECT t.id, t.parent_id, r.depth + 1
FROM tree_list r
JOIN tree t ON t.id = r.parent_id
)
SELECT t.id, t.parent_id, t.depth
FROM tree_list t
ORDER BY t.id;
Kết quả không có nhiều ý nghĩa đối với tôi, nhưng câu hỏi không xác định điều gì hợp lý hơn ..