postgresql實現樹狀查詢sql
先建立一張表TREE_TEST,表中有三個字段,分別是id,name和parent_idpost
CREATE TABLE TREE_TEST (
ID INTEGER PRIMARY KEY,
NAME VARCHAR(32),
PARENT_ID INTEGER REFERENCES TREE_TEST(ID)
);測試
而後插入幾條測試數據postgresql
INSERT INTO TREE_TEST(ID, NAME, PARENT_ID) VALUES(1, 'TREE_1', NULL);
INSERT INTO TREE_TEST(ID, NAME, PARENT_ID) VALUES(11, 'TREE_11', 1);
INSERT INTO TREE_TEST(ID, NAME, PARENT_ID) VALUES(12, 'TREE_12', 1);
INSERT INTO TREE_TEST(ID, NAME, PARENT_ID) VALUES(13, 'TREE_13', 1);
INSERT INTO TREE_TEST(ID, NAME, PARENT_ID) VALUES(111, 'TREE_111', 11);
INSERT INTO TREE_TEST(ID, NAME, PARENT_ID) VALUES(121, 'TREE_121', 12);
INSERT INTO TREE_TEST(ID, NAME, PARENT_ID) VALUES(122, 'TREE_122', 12);
INSERT INTO TREE_TEST(ID, NAME, PARENT_ID) VALUES(131, 'TREE_131', 13);
INSERT INTO TREE_TEST(ID, NAME, PARENT_ID) VALUES(132, 'TREE_132', 13);
INSERT INTO TREE_TEST(ID, NAME, PARENT_ID) VALUES(133, 'TREE_133', 13);遞歸
使用postgre中的recursive實現遞歸查詢數據
WITH RECURSIVE T(ID,NAME,PARENT_ID) AS(
SELECT ID,NAME,PARENT_ID FROM TREE_TEST WHERE ID =13
UNION ALL
SELECT T1.ID,T1.NAME,T1.PARENT_ID
FROM TREE_TEST T1 JOIN T ON T1.PARENT_ID=T.ID
)
SELECT ID,NAME,PARENT_ID FROM T查詢
這句話執行的步驟是:path
一、先執行語句SELECT ID,NAME,PARENT_ID FROM TREE_TEST WHERE ID =13
二、把上一步執行的結果做爲表T,而後用該表T與TREE_TEST實現UNION ALL查詢,並把查詢的結果做爲T,繼續這種UNION ALL,直到查詢完全部的子級葉子節點
三、執行最後面一句sql:SELECT ID,NAME,PARENT_ID FROM T
該語句是查詢出id爲13和13下全部的子集,查詢結果以下:
id name parent_id
13 TREE_13 1
131 TREE_131 13
132 TREE_132 13
133 TREE_133 13
固然也能夠把某個子級的深度查詢出來,sql以下:
WITH RECURSIVE T (ID, NAME, PARENT_ID, PATH, DEPTH) AS (
SELECT ID, NAME, PARENT_ID, ARRAY[ID] AS PATH, 1 AS DEPTH
FROM TREE_TEST
WHERE PARENT_ID IS NULL
UNION ALL
SELECT D.ID, D.NAME, D.PARENT_ID, T.PATH || D.ID, T.DEPTH + 1 AS DEPTH
FROM TREE_TEST D
JOIN T ON D.PARENT_ID = T.ID
)
SELECT ID, NAME, PARENT_ID, PATH, DEPTH FROM T
ORDER BY PATH;
該語句查詢結果以下:
id name parent_id path depth 1 TREE_1 {1} 1 11 TREE_11 1 {1,11} 2 111 TREE_111 11 {1,11,111} 3 12 TREE_12 1 {1,12} 2 121 TREE_121 12 {1,12,121} 3 122 TREE_122 12 {1,12,122} 3 13 TREE_13 1 {1,13} 2 131 TREE_131 13 {1,13,131} 3 132 TREE_132 13 {1,13,132} 3 133 TREE_133 13 {1,13,133} 3