这就是我的表(locationgroup)的样子。父/子关系正在同一个表中维护,并且可能有更多记录(ID可能不是按顺序)
+------+------------+------------+--------------+---------------+-----------+
| id | name | parentid | customerid | type | deleted |
|------+------------+------------+--------------+---------------+-----------|
| 131 | Zone | 0 | 79 | zone | False |
| 132 | State | 131 | 79 | state | False |
| 136 | Center 3 | 133 | 79 | servicecentre | False |
| 134 | Center 1 | 133 | 79 | servicecentre | False |
| 135 | Center 2 | 133 | 79 | servicecentre | False |
| 133 | City | 132 | 79 | city | False |
| 137 | Center 4 | 133 | 79 | servicecentre | False |
+------+------------+------------+--------------+---------------+-----------+
我想要达到的目标是获得任何给定身份的父母和孩子。
例如:对于id - 131
,结果应为
+------+------------+------------+--------------+---------------+-----------+
| id | name | parentid | customerid | type | deleted |
|------+------------+------------+--------------+---------------+-----------|
| 131 | Zone | 0 | 79 | zone | False |
| 132 | State | 131 | 79 | state | False |
| 133 | City | 132 | 79 | city | False |
| 134 | Center 1 | 133 | 79 | servicecentre | False |
| 135 | Center 2 | 133 | 79 | servicecentre | False |
| 136 | Center 3 | 133 | 79 | servicecentre | False |
| 137 | Center 4 | 133 | 79 | servicecentre | False |
+------+------------+------------+--------------+---------------+-----------+
因此,对于id - 137
,结果应为
+------+------------+------------+--------------+---------------+-----------+
| id | name | parentid | customerid | type | deleted |
|------+------------+------------+--------------+---------------+-----------|
| 131 | Zone | 0 | 79 | zone | False |
| 132 | State | 131 | 79 | state | False |
| 133 | City | 132 | 79 | city | False |
| 137 | Center 4 | 133 | 79 | servicecentre | False |
+------+------------+------------+--------------+---------------+-----------+
我只能通过查询获得子记录
WITH RECURSIVE locgrp AS (
SELECT
lg.*
FROM locationgroup lg
WHERE lg.customerid = 79 AND lg.id IN (133) AND lg.deleted = FALSE
UNION
SELECT
lg_union_1.*
FROM locationgroup lg_union_1
INNER JOIN locgrp lg_union_2 ON lg_union_1.parentid = lg_union_2.id
WHERE lg_union_1.deleted = FALSE AND lg_union_2.deleted = FALSE
)
SELECT *
FROM locgrp ORDER BY id ASC;
例如:对于id - 137
,我得到的是
+------+------------+------------+--------------+---------------+-----------+
| id | name | parentid | customerid | type | deleted |
|------+------------+------------+--------------+---------------+-----------|
| 137 | Center 4 | 133 | 79 | servicecentre | False |
+------+------------+------------+--------------+---------------+-----------+
我可以通过改变行
来达到预期的效果 INNER JOIN locgrp lg_union_2 ON lg_union_1.parentid = lg_union_2.id
在查询中
INNER JOIN locgrp lg_union_2 ON lg_union_1.id = lg_union_2.parentid
但是他们出于同样的目的而进行了两次不同的查询。
如何修改我的查询以获取具有相同查询的父记录和子记录。我应该坚持使用递归查询或其他任何东西。
答案 0 :(得分:0)
因为你对一个功能很好,所以这样的事情应该有效。我并不假装这是最酷的东西,但我相信它会产生正确的结果:
CREATE OR REPLACE FUNCTION recurse_me(cust_id integer, loc_id integer)
RETURNS SETOF locationgroup AS
$BODY$
declare
rw locationgroup%rowtype;
begin
FOR rw IN
WITH RECURSIVE locgrp AS (
SELECT
lg.*
FROM locationgroup lg
WHERE lg.customerid = cust_id AND lg.id = loc_id AND lg.deleted = FALSE
UNION
SELECT
lg_union_1.*
FROM locationgroup lg_union_1
INNER JOIN locgrp lg_union_2 ON lg_union_1.parentid = lg_union_2.id
WHERE lg_union_1.deleted = FALSE AND lg_union_2.deleted = FALSE
)
SELECT * FROM locgrp
LOOP
return next rw;
END LOOP;
FOR rw IN
WITH RECURSIVE locgrp AS (
SELECT
lg.*
FROM locationgroup lg
WHERE lg.customerid = cust_id AND lg.id = loc_id AND lg.deleted = FALSE
UNION
SELECT
lg_union_1.*
FROM locationgroup lg_union_1
INNER JOIN locgrp lg_union_2 ON lg_union_1.id = lg_union_2.parentid
WHERE lg_union_1.deleted = FALSE AND lg_union_2.deleted = FALSE
)
SELECT * FROM locgrp where id != loc_id
LOOP
return next rw;
END LOOP;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
实现:
postgres=# select * from recurse_me (79, 133) order by id;
id | name | parentid | customerid | type | deleted
-----+--------------+----------+------------+-----------------+---------
131 | Zone | 0 | 79 | zone | f
132 | State | 131 | 79 | state | f
133 | City | 132 | 79 | city | f
134 | Center 1 | 133 | 79 | servicecentre | f
135 | Center 2 | 133 | 79 | servicecentre | f
136 | Center 3 | 133 | 79 | servicecentre | f
137 | Center 4 | 133 | 79 | servicecentre | f
(7 rows)
postgres=# select * from recurse_me (79, 137) order by id;
id | name | parentid | customerid | type | deleted
-----+--------------+----------+------------+-----------------+---------
131 | Zone | 0 | 79 | zone | f
132 | State | 131 | 79 | state | f
133 | City | 132 | 79 | city | f
137 | Center 4 | 133 | 79 | servicecentre | f
(4 rows)