เปเบเบฅเบฐเบเบปเบ ERP เบเบตเปเบชเบฑเบเบชเบปเบ เบซเบผเบฒเบเบซเบปเบงเปเปเบงเบเบกเบตเบฅเบฑเบเบชเบฐเบเบฐเปเบเบฑเบเบฅเบณเบเบฑเบเปเบกเบทเปเบญเบงเบฑเบเบเบธเบเบตเปเปเบเบฑเบเบญเบฑเบเบเบฝเบงเบเบฑเบเบเบฑเปเบเบขเบนเปเปเบ เบเบปเปเบโเปเบกเปโเบเบญเบโเบชเบฒเบโเบเบปเบงโเบเบฑเบโเบเบฑเบโเบเบฐโเบเบธโเบฅเบธเบโเปเบฅเบฐโเบฅเบนเบโเบซเบฅเบฒเบโ - เบเบตเปโเปเบกเปเบโเปเบเบโเบชเปเบฒเบโเบเบฒเบโเบเบฑเบโเบเบฑเปเบโเบเบญเบโเบงเบดโเบชเบฒโเบซเบฐโเบเบดเบ (เบชเบฒโเบเบฒโเบเบฑเบโเบซเบกเบปเบโเปเบซเบผเบปเปเบฒโเบเบตเปโ, เบเบฐโเปเบเบโเปเบฅเบฐโเบเบธเปเบกโเบเบฒเบโเปเบฎเบฑเบโเบงเบฝเบโ)โ, เปเบฅเบฐโเบฅเบฒเบโเบเบฒเบโเบชเบดเบโเบเปเบฒโ, เปเบฅเบฐโเบเบทเปเบโเบเบตเปโเบเบฒเบโเปเบฎเบฑเบโเบงเบฝเบโ, เปเบฅเบฐโเบเบนเบกโเบชเบฒเบโเบเบญเบโเบเบธเบโเบเบฒเบโ, ...
เปเบเบเบงเบฒเบกเปเบเบฑเบเบเบดเบ, เบเปเปเบกเบต
เบกเบตเบซเบผเบฒเบเบงเบดเบเบตเบเบตเปเบเบฐเปเบเบฑเบเบฎเบฑเบเบชเบฒเบเบปเปเบเปเบกเปเบเบฑเปเบเบเปเบฒเบงเปเบงเปเปเบ DBMS, เปเบเปเบกเบทเปเบเบตเปเบเบงเบเปเบฎเบปเบฒเบเบฐเบชเบธเบกเปเบชเปเบเบฒเบเปเบฅเบทเบญเบเบเบฝเบง:
CREATE TABLE hier(
id
integer
PRIMARY KEY
, pid
integer
REFERENCES hier
, data
json
);
CREATE INDEX ON hier(pid); -- ะฝะต ะทะฐะฑัะฒะฐะตะผ, ััะพ FK ะฝะต ะฟะพะดัะฐะทัะผะตะฒะฐะตั ะฐะฒัะพัะพะทะดะฐะฝะธะต ะธะฝะดะตะบัะฐ, ะฒ ะพัะปะธัะธะต ะพั PK
เปเบฅเบฐเปเบเบเบฐเบเบฐเบเบตเปเบเปเบฒเบเบเปเบฒเบฅเบฑเบเปเบเบดเปเบเปเบเบปเปเบฒเปเบเปเบเบเบงเบฒเบกเปเบฅเบดเบเบเบญเบเบฅเปเบฒเบเบฑเบเบเบฑเปเบ, เบกเบฑเบเบฅเปเบเปเบฒเบขเปเบฒเบเบญเบปเบเบเบปเบเปเบเบทเปเบญเปเบเบปเปเบฒเปเบเปเบเบดเปเบเบงเบดเบเบตเบเบฒเบเปเบฎเบฑเบเบงเบฝเบเบเบตเป "เปเบเป" เบเบญเบเปเบเบปเปเบฒเบเบฑเบเปเบเบเบชเปเบฒเบเบเบฑเปเบเบเปเบฒเบงเบเบฐเปเบเบฑเบเปเบเบงเปเบ.
เปเบซเปเปเบเบดเปเบเบเบฑเบเบซเบฒเบเบปเปเบงเปเบเบเบตเปเปเบเบตเบเบเบทเปเบ, เบเบฒเบเบเบฐเบเบดเบเบฑเบเบเบญเบเบเบงเบเปเบเบปเบฒเปเบ SQL, เปเบฅเบฐเบเบฐเบเบฒเบเบฒเบกเบเบฑเบเบเบธเบเบเบฒเบเบเบฐเบเบดเบเบฑเบเบเบญเบเบเบงเบเปเบเบปเบฒ.
#1. เบเบธเบกเบเบฐเบเปเบฒเบเปเบฅเบดเบเปเบเบปเปเบฒเปเบ?
เปเบซเปเบเบงเบเปเบฎเบปเบฒ, เบชเปเบฒเบฅเบฑเบเบเปเบฒเบเบดเบเบฒเบก, เบเบญเบกเบฎเบฑเบเบงเปเบฒเปเบเบเบชเปเบฒเบเบเบตเปเบเบฐเบชเบฐเบเปเบญเบเปเบซเปเปเบซเบฑเบ subordination เบเบญเบเบเบฐเปเบเบเปเบเปเบเบเบชเปเบฒเบเบเบญเบเบญเบปเบเบเบฒเบเบเบฑเบเบเบฑเปเบ: เบเบฐเปเบเบเบเบฒเบ, เบเบฐเปเบเบ, เบเบฐเปเปเบเบเบฒเบ, เบชเบฒเบเบฒ, เบเบธเปเบกเปเบฎเบฑเบเบงเบฝเบ ... - เปเบเบเปเปเบเบฒเบกเบเบตเปเบเปเบฒเบเปเบเบซเบฒเบเบงเบเปเบเบปเบฒ.
เบเปเบฒเบญเบดเบ, เปเบซเปเบชเปเบฒเบ 'เบเบปเปเบเปเบกเป' เบเบญเบเบเบงเบเปเบฎเบปเบฒเบเบญเบเบญเบปเบเบเบฐเบเบญเบ 10K
INSERT INTO hier
WITH RECURSIVE T AS (
SELECT
1::integer id
, '{1}'::integer[] pids
UNION ALL
SELECT
id + 1
, pids[1:(random() * array_length(pids, 1))::integer] || (id + 1)
FROM
T
WHERE
id < 10000
)
SELECT
pids[array_length(pids, 1)] id
, pids[array_length(pids, 1) - 1] pid
FROM
T;
เปเบซเปเปเบฅเบตเปเบกเบเบปเปเบเบเปเบงเบเบงเบฝเบเบเบฒเบเบเบตเปเบเปเบฒเบเบเบฒเบเบเบตเปเบชเบธเบ - เบเบญเบเบซเบฒเบเบฐเบเบฑเบเบเบฒเบเบเบฑเบเบซเบกเบปเบเบเบตเปเปเบฎเบฑเบเบงเบฝเบเบขเบนเปเปเบเบเบฐเปเบซเบเบเบเบฒเบเบชเบฐเปเบเบฒเบฐ, เบซเบผเบทเปเบเปเบเบทเปเบญเบเปเบเบเบญเบเบฅเปเบฒเบเบฑเบเบเบฑเปเบ - เบเบญเบเบซเบฒเปเบเบฑเบเบเปเบญเบเบเบฑเบเบซเบกเบปเบเบเบญเบ node. เบกเบฑเบเบเปเปเบเบฐเปเบเบฑเบเบเบฒเบเบเบตเบเบตเปเบเบฐเปเบเปเบฎเบฑเบ "เบเบงเบฒเบกเปเบฅเบดเบ" เบเบญเบเบฅเบนเบเบซเบฅเบฒเบ ... เบเบฑเบเบซเบกเบปเบเบเบตเปเบญเบฒเบเบเบฐเบกเบตเบเบงเบฒเบกเบเปเบฒเปเบเบฑเบ, เบชเปเบฒเบฅเบฑเบเบเบฒเบเบเบปเบเบเบปเบงเบขเปเบฒเบ, เบเบฒเบเบเปเปเบชเปเบฒเบเบเบฒเบเบเบฐเปเบเบ.
เบเบธเบเบขเปเบฒเบเบเบปเบเบเบฐเบเบตเบเปเบฒเบกเบตเบฅเบนเบเบซเบฅเบฒเบเปเบซเบผเบปเปเบฒเบเบตเปเบเบฝเบเปเบเปเบชเบญเบเบชเบฒเบกเบฅเบฐเบเบฑเบ เปเบฅเบฐเบเบปเบงเปเบฅเบเปเบกเปเบเบเบฒเบเปเบเบชเบดเบเปเบเบปเบ, เปเบเปเบเปเบฒเบกเบตเบซเบผเบฒเบเบเบงเปเบฒ 5 เบเบฑเปเบ, เปเบฅเบฐเบกเบตเบฅเบนเบเบซเบฅเบฒเบเบซเบผเบฒเบเบชเบดเบเบเบปเบ, เบญเบฒเบเบเบฐเบกเบตเบเบฑเบเบซเบฒ. เบเปเปเบซเปเปเบเบดเปเบเบงเบดเบเบตเบเบฒเบเบเบปเปเบเบซเบฒเปเบเบเบเบฑเปเบเปเบเบตเบกเบเบญเบเบเบปเบงเปเบฅเบทเบญเบเบเบฒเบเบเบปเปเบเบซเบฒเปเบเบเบเบฑเปเบเปเบเบตเบกเบเบทเบเบเบฝเบ (เปเบฅเบฐเปเบฎเบฑเบเบงเบฝเบ). เปเบเปเบเปเบฒเบญเบดเบ, เปเบซเปเบเปเบฒเบเบปเบเบงเปเบฒเบเปเปเปเบเบเบฐเปเบเบฑเบเบเบตเปเบซเบเปเบฒเบชเบปเบเปเบเบซเบผเบฒเบเบเบตเปเบชเบธเบเบชเปเบฒเบฅเบฑเบเบเบฒเบเบเบปเปเบเบเบงเปเบฒเบเบญเบเบเบงเบเปเบฎเบปเบฒ.
เบชเปเบงเบเปเบซเบเป "เปเบฅเบดเบ" เบเบปเปเบเปเบกเปเบเปเบญเบ:
WITH RECURSIVE T AS (
SELECT
id
, pid
, ARRAY[id] path
FROM
hier
WHERE
pid IS NULL
UNION ALL
SELECT
hier.id
, hier.pid
, T.path || hier.id
FROM
T
JOIN
hier
ON hier.pid = T.id
)
TABLE T ORDER BY array_length(path, 1) DESC;
id | pid | path
---------------------------------------------
7624 | 7623 | {7615,7620,7621,7622,7623,7624}
4995 | 4994 | {4983,4985,4988,4993,4994,4995}
4991 | 4990 | {4983,4985,4988,4989,4990,4991}
...
เบชเปเบงเบเปเบซเบเป "เบเบงเปเบฒเบ" เบเบปเปเบเปเบกเปเบเปเบญเบ:
...
SELECT
path[1] id
, count(*)
FROM
T
GROUP BY
1
ORDER BY
2 DESC;
id | count
------------
5300 | 30
450 | 28
1239 | 27
1573 | 25
เบชเปเบฒเบฅเบฑเบเบเบฒเบเบชเบญเบเบเบฒเบกเปเบซเบผเบปเปเบฒเบเบตเปเบเบงเบเปเบฎเบปเบฒเปเบเปเปเบเปเปเบเบเบเบปเบเบเบฐเบเบด เปเบเบปเปเบฒเบฎเปเบงเบก recursive:
เปเบเปเบเบญเบ, เบเปเบงเบเบฎเบนเบเปเบเบเบเบฒเบเบฎเปเบญเบเบเปเบเบตเป เบเปเบฒเบเบงเบเบเบฒเบเบเปเปเบฒเบเบทเบเบเบฐเบเบปเบเบเบฑเบเบเปเบฒเบเบงเบเบฅเบนเบเบซเบฅเบฒเบเบเบฑเบเปเบปเบ (เปเบฅเบฐเบกเบตเบซเบผเบฒเบเบญเบฒเบเปเบเบฑเบชเบเบญเบเบเบงเบเปเบเบปเบฒ), เปเบฅเบฐเบเบตเปเบชเบฒเบกเบฒเบเปเบเปเปเบงเบฅเบฒเบเบฑเบเบเบฐเบเบฒเบเบญเบเบเบตเปเบชเปเบฒเบเบฑเบ, เปเบฅเบฐ, เบเบฑเปเบเบเบฑเปเบ, เปเบงเบฅเบฒ.
เปเบซเปเบเบงเบเปเบเบดเปเบเบเบปเปเบเปเบกเปเบเปเบญเบ "เบเบงเปเบฒเบเบเบตเปเบชเบธเบ":
WITH RECURSIVE T AS (
SELECT
id
FROM
hier
WHERE
id = 5300
UNION ALL
SELECT
hier.id
FROM
T
JOIN
hier
ON hier.pid = T.id
)
TABLE T;
เบเบฑเปเบเบเบตเปเบเบฒเบเปเบงเป, เบเบงเบเปเบฎเบปเบฒเบเบปเบเปเบซเบฑเบเบเบฑเบเปเบปเบ 30 เบเบฑเบเบเบถเบ. เปเบเปเบเบงเบเปเบเบปเบฒเปเบเปเปเบงเบฅเบฒ 60% เบเบญเบเปเบงเบฅเบฒเบเบฑเบเบซเบกเบปเบเปเบเปเบฅเบทเปเบญเบเบเบตเป - เปเบเบฒเบฐเบงเปเบฒเบเบงเบเปเบเบปเบฒเบเบฑเบเปเบฎเบฑเบ 30 เบเบปเปเบเบซเบฒเปเบเบเบฑเบเบชเบฐเบเบต. เบกเบฑเบเปเบเบฑเบเปเบเปเบเปเบเบตเปเบเบฐเปเบฎเบฑเบเบซเบเปเบญเบเบฅเบปเบเบเป?
เบเบงเบโเบชเบญเบโเบซเบผเบฒเบโเปเบเบโเบเบฑเบโเบเบฐโเบเบตโ
เบเบงเบเปเบฎเบปเบฒเบเปเบฒเปเบเบฑเบเบเปเบญเบเปเบฎเบฑเบเบเบฒเบเบชเบญเบเบเบฒเบกเบเบฑเบเบชเบฐเบเบตเปเบเบเบเปเบฒเบเบซเบฒเบเบชเปเบฒเบฅเบฑเบเปเบเปเบฅเบฐ node? เบกเบฑเบ turns เปเบซเปเปเบซเบฑเบเบงเปเบฒเบเปเป - เบเบงเบเปเบฎเบปเบฒเบชเบฒเบกเบฒเบเบญเปเบฒเบเบเบฒเบเบเบฑเบเบเบฐเบเบต เปเบเปเบเบฐเปเบเบซเบผเบฒเบเบญเบฑเบเบเปเบญเบกเบเบฑเบเปเบเบชเบฒเบเบเบฝเบง เปเบเบเบเบฒเบเบเปเบงเบเปเบซเบผเบทเบญ = ANY(array)
.
เปเบฅเบฐเปเบเปเบเปเบฅเบฐเบเบธเปเบกเบเบปเบงเบฅเบฐเบเบธเบเบฑเปเบเบเปเบฒเบงเบเบงเบเปเบฎเบปเบฒเบชเบฒเบกเบฒเบเปเบญเบปเบฒ ID เบเบฑเบเบซเบกเบปเบเบเบตเปเบเบปเบเปเบเบเบฑเปเบเบเบญเบเบเบตเปเบเปเบฒเบเบกเบฒเปเบเบ "nodes". เบเบฑเปเบเปเบกเปเบ, เปเบเปเบเปเบฅเบฐเบเบฑเปเบเบเบญเบเบเปเปเปเบเบเบงเบเปเบฎเบปเบฒเบเบฐ เบเบญเบโเบซเบฒโเบฅเบนเบโเบซเบฅเบฒเบโเบเบฑเบโเบซเบกเบปเบโเบเบญเบโเบฅเบฐโเบเบฑเบโเปเบโเบซเบเบถเปเบโเปเบโเปเบงโเบฅเบฒโเบเบฝเบงโ.
เบเบฝเบเปเบเป, เบเบตเปเปเบกเปเบเบเบฑเบเบซเบฒ, เปเบเบเบฒเบเบเบฑเบเปเบฅเบทเบญเบ recursive, เบเปเบฒเบเบเปเปเบชเบฒเบกเบฒเบเปเบเบปเปเบฒเปเบเบดเบเบเบปเบงเบกเบฑเบเปเบญเบเปเบเบเบฒเบเบชเบญเบเบเบฒเบกเบเบตเปเบเปเบญเบเบเบฑเบ, เปเบเปเบเบงเบเปเบฎเบปเบฒเบเปเบฒเปเบเบฑเบเบเปเบญเบ somehow เปเบฅเบทเบญเบเบเบฝเบเปเบเปเบชเบดเปเบเบเบตเปเบเบปเบเปเบซเบฑเบเบขเบนเปเปเบเบฅเบฐเบเบฑเบเบเบตเปเบเปเบฒเบเบกเบฒ ... เบกเบฑเบ turns เปเบซเปเปเบซเบฑเบเบงเปเบฒเบกเบฑเบเปเบเบฑเบเปเบเบเปเปเปเบเปเบเบตเปเบเบฐเปเบฎเบฑเบเบเบฒเบเบชเบญเบเบเบฒเบก nested เบชเปเบฒเบฅเบฑเบเบเบฒเบเบเบฑเบเปเบฅเบทเบญเบเบเบฑเบเบซเบกเบปเบ, เปเบเปเบชเปเบฒเบฅเบฑเบเบเบฒเบเบชเบฐเบซเบเบฒเบกเบชเบฐเปเบเบฒเบฐเบเบญเบเบกเบฑเบเปเบเบฑเบเปเบเปเบเป. เปเบฅเบฐเบเบฒเบเบชเบฐเบซเบเบฒเบกเบเบตเปเบเบฑเบเบชเบฒเบกเบฒเบเปเบเบฑเบ array - เปเบเบดเปเบเปเบกเปเบเบชเบดเปเบเบเบตเปเบเบงเบเปเบฎเบปเบฒเบเปเบญเบเบเบฒเบเปเบเป ANY
.
เบกเบฑเบเบเบฑเบเบเบทเบเปเบฒเปเบฅเบฑเบเบเปเบญเบ, เปเบเปเปเบเปเบเบเบงเบฒเบเบเบธเบเบขเปเบฒเบเปเบกเปเบเบเปเบฒเบเบเบฒเบ.
WITH RECURSIVE T AS (
SELECT
ARRAY[id] id$
FROM
hier
WHERE
id = 5300
UNION ALL
SELECT
ARRAY(
SELECT
id
FROM
hier
WHERE
pid = ANY(T.id$)
) id$
FROM
T
WHERE
coalesce(id$, '{}') <> '{}' -- ััะปะพะฒะธะต ะฒัั
ะพะดะฐ ะธะท ัะธะบะปะฐ - ะฟัััะพะน ะผะฐััะธะฒ
)
SELECT
unnest(id$) id
FROM
T;
เปเบฅเบฐเปเบเบเบตเปเบเบตเปเบชเบดเปเบเบเบตเปเบชเปเบฒเบเบฑเบเบเบตเปเบชเบธเบเบเปเปเปเบกเปเบเปเบเป เบเบฐเบเบฐ 1.5 เบเบฑเปเบเปเบเปเบงเบฅเบฒ, เปเบฅเบฐเบงเปเบฒเบเบงเบเปเบฎเบปเบฒเบฅเบปเบ buffers เบซเบเปเบญเบเบฅเบปเบ, เปเบเบฒเบฐเบงเปเบฒเบเบงเบเปเบฎเบปเบฒเบกเบตเบเบฝเบเปเบเป 5 เปเบเปเบเบซเบฒเบเบฑเบเบเบฐเบเบตเปเบเบเบเบตเปเบเบฐเปเบเบฑเบ 30!
เปเบเบเบฑเบเปเบเบตเปเบกเปเบเบตเบกเปเบกเปเบเบเบงเบฒเบกเบเบดเบเบเบตเปเบงเปเบฒเบซเบผเบฑเบเบเบฒเบ unnest เบชเบธเบเบเปเบฒเบ, เบเบปเบงเบเปเบฒเบเบปเบเบเบฐเบเบฑเบเบเบปเบเบเปเบฒเบชเบฑเปเบเปเบเบ "เบฅเบฐเบเบฑเบ".
เบเปเบฒเบ node
เบเบฒเบเบเบดเบเบฒเบฅเบฐเบเบฒเบเปเปเปเบเบเบตเปเบเบฐเบเปเบงเบเปเบซเปเบเบฒเบเบเบฑเบเบเบธเบเบเบฒเบเบเบฐเบเบดเบเบฑเบเปเบกเปเบ โ "เปเบ" เบเปเปเบชเบฒเบกเบฒเบเบกเบตเบฅเบนเบเปเบเป, เบเบฑเปเบเปเบกเปเบ, เบชเปเบฒเบฅเบฑเบเบเบงเบเปเบเบปเบฒเบเปเปเบเปเบฒเปเบเบฑเบเบเปเบญเบเปเบเบดเปเบ "เบฅเบปเบ" เปเบฅเบตเบ. เปเบเบเบฒเบเบเปเบฒเบเบปเบเบงเบฝเบเบเบฒเบเบเบญเบเบเบงเบเปเบฎเบปเบฒ, เบเบตเปเบซเบกเบฒเบเบเบงเบฒเบกเบงเปเบฒเบเปเบฒเบเบงเบเปเบฎเบปเบฒเบเบฐเบเบดเบเบฑเบเบเบฒเบกเบฅเบฐเบเบปเบเบเปเบญเบเปเบชเปเบเบญเบเบเบฐเปเบเบเบเบฒเบเปเบฅเบฐเบเบฑเบเบฅเบธเบเบฐเบเบฑเบเบเบฒเบ, เบซเบผเบฑเบเบเบฒเบเบเบฑเปเบเบเปเปเบเปเบฒเปเบเบฑเบเบเปเบญเบเบเบญเบเบซเบฒเบชเบฒเบเบฒเบเบตเปเบเบทเปเบกเบญเบตเบ.
เปเบซเปเปเบเบปเปเบฒเปเบเปเบเบเบฒเบเบฐเบฅเบฒเบเบเบญเบเบเบงเบเปเบฎเบปเบฒ เปเบเบตเปเบกเปเบเบตเบก boolean
- เบเบฒเบเบชเบฐเบซเบเบฒเบก, เปเบเบดเปเบเบเบฑเบเบเบตเบเบฐเบเบญเบเบเบงเบเปเบฎเบปเบฒเบงเปเบฒเบเบตเปเบชเบฐเปเบเบฒเบฐเบขเบนเปเปเบเบเบปเปเบเปเบกเปเบเบญเบเบเบงเบเปเบฎเบปเบฒเปเบกเปเบ "เบเปเป" - เบเบฑเปเบเปเบกเปเบ, เบเปเปเบงเปเบฒเบเบฐเปเบเบฑเบเบกเบฑเบเบชเบฒเบกเบฒเบเบกเบตเปเบเบทเปเบญเบชเบฒเบเบเบฑเบเบซเบกเบปเบ.
ALTER TABLE hier
ADD COLUMN branch boolean;
UPDATE
hier T
SET
branch = TRUE
WHERE
EXISTS(
SELECT
NULL
FROM
hier
WHERE
pid = T.id
LIMIT 1
);
-- ะะฐะฟัะพั ััะฟะตัะฝะพ ะฒัะฟะพะปะฝะตะฝ: 3033 ัััะพะบ ะธะทะผะตะฝะตะฝะพ ะทะฐ 42 ะผั.
เบเบดเปเบเปเบซเบเป! เบกเบฑเบ turns เปเบซเปโเปเบซเบฑเบโเบงเปเบฒโเบเบฝเบโเปเบฅเบฑเบโเบเปเบญเบโเบซเบผเบฒเบโเบโเปโเบงเบฒ 30โ% เบเบญเบโเบญเบปเบโเบเบฐโเบเบญเบโเบเบญเบโเบเบปเปเบโเปเบกเปโเบเบฑเบโเบซเบกเบปเบโเบกเบตโเบฅเบนเบโเบซเบฅเบฒเบโ.
เบเบญเบเบเบตเปเปเบซเปเปเบเปเบเบปเบเปเบเบเบตเปเปเบเบเบเปเบฒเบเบเบฑเบเปเบฅเบฑเบเบเปเบญเบ - เบเบฒเบเปเบเบทเปเบญเบกเบเปเปเบเบฑเบเบเบฒเบเบชเปเบงเบ recursive เบเปเบฒเบ LATERAL
, เปเบเบดเปเบเบเบฐเบเปเบงเบเปเบซเปเบเบงเบเปเบฎเบปเบฒเปเบเบปเปเบฒเปเบเบดเบเบเบปเปเบเบเบฒเบเบญเบ "เบเบฒเบเบฐเบฅเบฒเบ" recursive เบเบฑเบเบเบต, เปเบฅเบฐเบเปเบฒเปเบเปเบซเบเปเบฒเบเบตเปเบฅเบงเบกเบเบตเปเบกเบตเปเบเบทเปเบญเบเปเบเบเบฒเบเบเบฑเปเบเบเบญเบเปเบเบเบญเบตเบเปเบชเป node เปเบเบทเปเบญเบซเบผเบธเบเบเปเบญเบเบเบธเบเบเบญเบเบเบต:
WITH RECURSIVE T AS (
SELECT
array_agg(id) id$
, array_agg(id) FILTER(WHERE branch) ns$
FROM
hier
WHERE
id = 5300
UNION ALL
SELECT
X.*
FROM
T
JOIN LATERAL (
SELECT
array_agg(id) id$
, array_agg(id) FILTER(WHERE branch) ns$
FROM
hier
WHERE
pid = ANY(T.ns$)
) X
ON coalesce(T.ns$, '{}') <> '{}'
)
SELECT
unnest(id$) id
FROM
T;
เบเบงเบโเปเบฎเบปเบฒโเบชเบฒโเบกเบฒเบโเบซเบผเบธเบโเบเปเบญเบโเบเบฒเบโเปเบโเบเบฑเบโเบเบฐโเบเบตโเบญเบตเบโเบซเบเบถเปเบโเปเบฅเบฐโ เบเบฐเบเบฐเบซเบผเบฒเบเบเบงเปเบฒ 2 เบเบฑเปเบเปเบเบเบฐเบฅเบดเบกเบฒเบ เบเบดเบชเบนเบ.
#2. เปเบซเปเบเบฑเบเบเบทเบเปเบเบซเบฒเบฎเบฒเบ
เบชเบนเบเบเบฒเบเบเบดเบเปเบฅเปเบเบตเปเบเบฐเปเบเบฑเบเบเบฐเปเบซเบเบเบเปเบฒเบเปเบฒเบเบเปเบญเบเบเบฒเบเปเบเบฑเบเบเปเบฒเบเปเปเบกเบนเบเบชเปเบฒเบฅเบฑเบเบญเบปเบเบเบฐเบเบญเบเบเบฑเบเบซเบกเบปเบ "เบเบถเปเบเบเบปเปเบเปเบกเป", เปเบเบเบฐเบเบฐเบเบตเปเปเบเบฑเบเบฎเบฑเบเบชเบฒเบเปเปเบกเบนเบเบเปเบฝเบงเบเบฑเบเปเบญเบเบฐเบชเบฒเบเปเบซเบผเปเบเปเบ (เปเบฅเบฐเบกเบตเบเบปเบงเบเบตเปเบงเบฑเบเบญเบฑเบเปเบ) เบเบตเปเปเบฎเบฑเบเปเบซเปเบกเบฑเบเบเบทเบเบฅเบงเบกเปเบเบปเปเบฒเปเบเบเบปเบงเบขเปเบฒเบ - เบเบปเบงเบขเปเบฒเบ, เบเบฒเบเบชเปเบฒเบเบเบปเบเบฅเบฒเบเบเบฒเบเบชเบฐเบซเบผเบธเบ. เบเปเบงเบเบเบฒเบเบฅเบงเบเบฅเบงเบกเปเบเบปเปเบฒเปเบเปเบ nodes.
เบชเบดเปเบเบเบตเปเบเปเปเปเบเบเบตเปเบเบงเบเบเบฐเบเบทเบเบเบฐเบเบดเบเบฑเบเบเบฝเบเปเบเปเปเบเบฑเบเบซเบผเบฑเบเบเบฒเบเบชเบฐเปเบเบเปเบเบงเบเบงเบฒเบกเบเบดเบ, เบเบฑเบเบเบฑเปเบเปเบเปเบเปเบฒเบฎเปเบญเบเบเปเปเบเปเบเบฒเบเปเบเบฑเบเปเบฅเบทเปเบญเบเบเบตเปเบซเบเบธเปเบเบเบฒเบเบซเบผเบฒเบ. เปเบเปเบเปเบฒเบกเบฑเบเบเบญเบเบเปเบฒเบเบฒเบเบเปเปเบกเบนเบเบเบญเบเปเบเบปเปเบฒ, เบเปเบฒเบเบเบงเบเบเบดเบเบเปเบฝเบงเบเบฑเบเบเบฒเบเปเบเปเปเบเบฑเบเบเบดเบเบเบตเปเบเปเบฒเบเบเบทเบเบฑเบ.
เปเบซเปเปเบฅเบตเปเบกเบเบปเปเบเบเปเบงเบเบชเบญเบเบชเบฒเบกเบเปเบฒเบเบตเปเบเปเบฒเบเบเบฒเบ:
- เบเบฑเบเบเบถเบเบเบฝเบงเบเบฑเบเบเบฒเบเบเบฒเบเบเปเปเบกเบนเบ เบกเบฑเบเบเบตเบเบตเปเบชเบธเบเบเบตเปเบเบฐเบญเปเบฒเบเบกเบฑเบเปเบเบทเปเบญเบเบฝเบง.
- เบเบฑเบเบเบถเบเบเบฒเบเบเบฒเบเบเปเปเบกเบนเบ เบกเบฑเบเบกเบตเบเบฐเบชเบดเบเบเบดเบเบฒเบเบซเบผเบฒเบเปเบเบเบฒเบเบญเปเบฒเบเปเบเบฑเบเบเบธเบเบเบงเปเบฒเบเบปเบเบเบฝเบง.
เบเบญเบเบเบตเปเปเบซเปเบเบฐเบเบฒเบเบฒเบกเบชเปเบฒเบเบเปเบฒเบฎเปเบญเบเบเปเบเบตเปเบเบงเบเปเบฎเบปเบฒเบเปเบญเบเบเบฒเบ.
เบเบฑเปเบเบเบญเบ 1
เปเบเปเบเบญเบ, เปเบกเบทเปเบญเปเบฅเบตเปเบกเบเบปเปเบ recursion (เบเปเบญเบเบเบตเปเบเบงเบเปเบฎเบปเบฒเบเบฐเบเปเปเบกเบตเบกเบฑเบ!) เบเบงเบเปเบฎเบปเบฒเบเบฐเบเปเบญเบเบฅเบปเบเบเบฑเบเบเบถเบเบเบญเบเปเบเบเปเบงเบเบเบปเบเปเบญเบเปเบเบเบญเบตเบเปเบชเปเบเบธเบเบเบญเบเบเบปเบงเบฅเบฐเบเบธเปเบเบทเปเบญเบเบเบปเปเบ:
WITH RECURSIVE tree AS (
SELECT
rec -- ััะพ ัะตะปัะฝะฐั ะทะฐะฟะธัั ัะฐะฑะปะธัั
, id::text chld -- ััะพ "ะฝะฐะฑะพั" ะฟัะธะฒะตะดัะธั
ััะดะฐ ะธัั
ะพะดะฝัั
ะปะธัััะตะฒ
FROM
hier rec
WHERE
id = ANY('{1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192}'::integer[])
UNION ALL
...
เบเปเบฒเบกเบฑเบเปเบเบดเปเบเบเบทเบงเปเบฒเปเบเบเบเบฐเบซเบฅเบฒเบเบเบฑเบเบเบนเปเปเบเบเบนเปเบเบถเปเบเบเบตเป "เบเบธเบ" เบเบทเบเปเบเบฑเบเปเบงเปเปเบเบฑเบเบชเบฐเบเบฃเบดเบเปเบฅเบฐเบเปเปเปเบกเปเบ array, เบซเบผเบฑเบเบเบฒเบเบเบฑเปเบเบกเบตเบเปเบฒเบญเบฐเบเบดเบเบฒเบเบเปเบฒเบเปเบชเปเบฒเบฅเบฑเบเปเบฅเบทเปเบญเบเบเบตเป. เบกเบตเบเบฑเบเบเบฑเบ "gluing" เบเบฐเบชเบปเบกเบเบฐเบชเบฒเบเปเบเบเบปเบงเบชเปเบฒเบฅเบฑเบเบชเบฒเบ string_agg
, เปเบเปเบเปเปเปเบกเปเบเบชเปเบฒเบฅเบฑเบ arrays. เปเบเบดเบเปเบกเปเบเบงเปเบฒเบเบฒเบ
เบเบฑเปเบเบเบญเบ 2
เบเบญเบเบเบตเปเบเบงเบเปเบฎเบปเบฒเบเบฐเปเบเปเบฎเบฑเบเบเบธเบ ID เบเบฒเบเบชเปเบงเบเบเบตเปเบเบฐเบเปเบญเบเบญเปเบฒเบเบเบทเปเบกเบญเบตเบ. เปเบเบทเบญเบเบชเบฐเปเบซเบกเบตเบเบงเบเปเบเบปเบฒเบเบฐเบเบทเบเบเปเปเบฒเบเบฑเบเปเบเบเบฑเบเบเบถเบเบเบตเปเปเบเบเบเปเบฒเบเบเบฑเบเบเบญเบเบเบธเบเบเบปเปเบเบชเบฐเบเบฑเบ - เบเบฑเปเบเบเบฑเปเบเบเบงเบเปเบฎเบปเบฒเบเบฐ เบเบฑเบเบเบธเปเบกเปเบซเปเปเบเบปเบฒเปเบเบปเปเบฒ, เปเบเบเบฐเบเบฐเบเบตเปเบฎเบฑเบเบชเบฒเบเปเปเบกเบนเบเบเปเบฝเบงเบเบฑเบเปเบเปเบซเบผเปเบ.
เปเบเปเบเบตเปเบชเบฒเบกเบเบฑเบเบซเบฒเบฅเปเบเปเบฒเบเบงเบเปเบฎเบปเบฒ:
- เบเบฒเบเบชเปเบงเบ "subrecursive" เบเบญเบเบเบฒเบเบชเบญเบเบเบฒเบกเบเปเปเบชเบฒเบกเบฒเบเบกเบตเบซเบเปเบฒเบเบตเปเบฅเบงเบกเบเบฑเบ
GROUP BY
. - เบเบฒเบเบญเปเบฒเบเบญเบตเบเปเบเบดเบ "เบเบฒเบเบฐเบฅเบฒเบ" recursive เบเปเปเบชเบฒเบกเบฒเบเบขเบนเปเปเบ subquery เบเปเบญเบ.
- เบเบฒเบเบฎเปเบญเบเบเปเบขเบนเปเปเบเบเบฒเบเบชเปเบงเบ recursive เบเปเปเบชเบฒเบกเบฒเบเบกเบต CTE เปเบเป.
เปเบเบเบเบต, เบเบฑเบเบซเบฒเบเบฑเบเบซเบกเบปเบเปเบซเบผเบปเปเบฒเบเบตเปเปเบกเปเบเบเปเบญเบเบเปเบฒเบเบเปเบฒเบเบเบตเปเบเบฐเปเบฎเบฑเบเบงเบฝเบเบเบฐเบกเบฒเบ. เปเบซเปเปเบฅเบตเปเบกเบเบปเปเบเบเบฒเบเบเบตเปเบชเบธเบ.
CTE เปเบเบชเปเบงเบ recursive
เบเบตเปเบเบทเบเบฑเปเบเบเบฑเปเบ เบเปเป เปเบฎเบฑเบเบงเบฝเบ:
WITH RECURSIVE tree AS (
...
UNION ALL
WITH T (...)
SELECT ...
)
เปเบฅเบฐเบเบฑเปเบเบเบฑเปเบเบกเบฑเบเปเบฎเบฑเบเบงเบฝเบ, เบงเบปเบเปเบฅเบฑเบเปเบฎเบฑเบเปเบซเปเบเบงเบฒเบกเปเบเบเบเปเบฒเบ!
WITH RECURSIVE tree AS (
...
UNION ALL
(
WITH T (...)
SELECT ...
)
)
Nested query เบเปเปเบเบฑเบ "เบเบฒเบเบฐเบฅเบฒเบ" recursive
Hmm... CTE recursive เบเปเปเบชเบฒเบกเบฒเบเปเบเบปเปเบฒเปเบเบดเบเปเบเปเปเบเบเบฒเบเบชเบญเบเบเบฒเบกเบเปเบญเบ. เปเบเปเบกเบฑเบเบญเบฒเบเบเบฐเบขเบนเปเปเบ CTE! เปเบฅเบฐเบเบฒเบเบฎเปเบญเบเบเปเบเบตเปเบเปเบญเบเบเบฑเบเบชเบฒเบกเบฒเบเปเบเบปเปเบฒเปเบเบดเบ CTE เบเบตเปเปเบฅเปเบง!
GROUP BY เบเบฒเบเปเบ recursion
เบกเบฑเบเบเปเปเปเบเบฑเบเบเบตเปเบเปเปเบ, เปเบเป... เบเบงเบเปเบฎเบปเบฒเบกเบตเบงเบดเบเบตเบเปเบฒเบเปเบเบตเปเบเบฐเปเบฎเบฑเบเบเบฒเบกเปเบเบเบเบธเปเบกเปเบเบเบเบฒเบเปเบเป DISTINCT ON
เปเบฅเบฐโเบซเบเปเบฒโเบเปเบฒเบโเบซเบเปเบฒโเบเปเบฒเบโ!
SELECT
(rec).pid id
, string_agg(chld::text, ',') chld
FROM
tree
WHERE
(rec).pid IS NOT NULL
GROUP BY 1 -- ะฝะต ัะฐะฑะพัะฐะตั!
เปเบฅเบฐเบเบตเปเปเบกเปเบเบงเบดเบเบตเบเบฒเบเปเบฎเบฑเบเบงเบฝเบ!
SELECT DISTINCT ON((rec).pid)
(rec).pid id
, string_agg(chld::text, ',') OVER(PARTITION BY (rec).pid) chld
FROM
tree
WHERE
(rec).pid IS NOT NULL
เบเบฝเบงเบเบตเปเบเบงเบเปเบฎเบปเบฒเปเบซเบฑเบเบงเปเบฒเปเบเบฑเบเบซเบเบฑเบ ID เบเบปเบงเปเบฅเบเบเบถเปเบเบเบทเบเบเปเบฝเบเปเบเบฑเบเบเปเปเบเบงเบฒเบก - เปเบเบทเปเบญเปเบซเปเบเบงเบเปเบเบปเบฒเปเบเบปเปเบฒเบเบฑเบเปเบเปเปเบเบเปเบเบเบเปเบงเบเปเบเบทเปเบญเบเปเบฒเบเบเบธเบ!
เบเบฑเปเบเบเบญเบ 3
เบชเปเบฒเบฅเบฑเบเบชเบธเบเบเปเบฒเบเบเบงเบเปเบฎเบปเบฒเบเปเปเบกเบตเบซเบเบฑเบเปเบซเบผเบทเบญ:
- เบเบงเบเปเบฎเบปเบฒเบญเปเบฒเบ "เบเบฒเบเบชเปเบงเบ" เบเบฑเบเบเบถเบเปเบเบเบญเบตเบเปเบชเปเบเบธเบเบเบญเบ IDs เบเบธเปเบก
- เบเบงเบเปเบฎเบปเบฒเบชเบปเบกเบเบฝเบเบชเปเบงเบเบเบตเปเบเบทเบเบฅเบปเบเบเบฑเบ "เบเบธเบ" เบเบญเบเปเบเปเบเบเบปเปเบเบชเบฐเบเบฑเบ
- "เบเบฐเบซเบเบฒเบ" เปเบเบเบเบตเปเบเปเบฒเบเบปเบเปเบงเปเปเบเบเปเบเป
unnest(string_to_array(chld, ',')::integer[])
WITH RECURSIVE tree AS (
SELECT
rec
, id::text chld
FROM
hier rec
WHERE
id = ANY('{1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192}'::integer[])
UNION ALL
(
WITH prnt AS (
SELECT DISTINCT ON((rec).pid)
(rec).pid id
, string_agg(chld::text, ',') OVER(PARTITION BY (rec).pid) chld
FROM
tree
WHERE
(rec).pid IS NOT NULL
)
, nodes AS (
SELECT
rec
FROM
hier rec
WHERE
id = ANY(ARRAY(
SELECT
id
FROM
prnt
))
)
SELECT
nodes.rec
, prnt.chld
FROM
prnt
JOIN
nodes
ON (nodes.rec).id = prnt.id
)
)
SELECT
unnest(string_to_array(chld, ',')::integer[]) leaf
, (rec).*
FROM
tree;
เปเบซเบผเปเบเบเปเปเบกเบนเบ: www.habr.com