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