แ แแฃแ ERP แกแแกแขแแแแแจแ แแแแ แแ แแแฃแแก แแฅแแก แแแ แแ แฅแแฃแแ แแฃแแแแแ แแแแกแแช แแ แแแแแ แแแแแ แแแแแฅแขแแแ แ แแแแแแ แฌแแแแแแ -แจแแแแแแแแแแแแก แฃแ แแแแ แแแแแก แฎแ - แแก แแ แแก แกแแฌแแ แแแก แแ แแแแแแแชแแฃแแ แกแขแ แฃแฅแขแฃแ แ (แงแแแแ แแก แคแแแแแแ, แแแแงแแคแแแแแ แแ แกแแแฃแจแแ แฏแแฃแคแแแ) แแ แกแแฅแแแแแก แแแขแแแแแ, แกแแแฃแจแแ แกแคแแ แแแแ แแ แแแงแแแแแแแก แแฃแแฅแขแแแแก แแแแแ แแคแแ,...
แคแแฅแขแแแ แแแแ, แแ แชแแ แแ แแ แแ แกแแแแแก
แแกแแแ แฎแแก DBMS-แจแ แจแแกแแแแฎแแ แแ แแแแแ แแแ แแ แกแแแแแก, แแแแ แแ แแฆแแก แฉแแแ แแฎแแแแ แแ แ แแแ แแแแขแแ แแแแแแแฎแแแแแแ แงแฃแ แแแฆแแแแก:
CREATE TABLE hier(
id
integer
PRIMARY KEY
, pid
integer
REFERENCES hier
, data
json
);
CREATE INDEX ON hier(pid); -- ะฝะต ะทะฐะฑัะฒะฐะตะผ, ััะพ FK ะฝะต ะฟะพะดัะฐะทัะผะตะฒะฐะตั ะฐะฒัะพัะพะทะดะฐะฝะธะต ะธะฝะดะตะบัะฐ, ะฒ ะพัะปะธัะธะต ะพั PK
แแ แกแแแแ แแแ แแ แฅแแแก แกแแฆแ แแแจแ แแงแฃแ แแแแ, แแก แแแแแแแแแแ แแแแแแแ, แแฃ แ แแแแแแแ [แแ แแแคแแฅแขแฃแ แ] แแฅแแแแ แแกแแ แกแขแ แฃแฅแขแฃแ แแกแแแ แแฃแจแแแแแก แแฅแแแแ โแแฃแแฃแแ แงแแแแโ แแแแแ.
แแแแแ แแแแแแฎแแแแ แฌแแ แแแจแแแแ แขแแแฃแ แแ แแแแแแแแก, แแแ แแแแแ แแแแก SQL-แจแ แแ แจแแแแชแแแแ แแแแแฃแแฏแแแแกแแ แแแแ แจแแกแ แฃแแแแ.
#1. แ แแแแแแแ แฆแ แแแ แแฃแ แแฆแแแก แฎแแ แแแ?
แแแแแ, แแแแฃแกแขแแแแกแแแแก แแแแแฆแแ, แ แแ แแก แกแขแ แฃแฅแขแฃแ แ แแแกแแฎแแแ แแ แแแแแแแชแแแก แกแขแ แฃแฅแขแฃแ แแจแ แแแแแ แขแแแแแขแแแแก แแแฅแแแแแแแแ แแแแจแ: แแแแงแแคแแแแแแแ, แแแแงแแคแแแแแแแ, แกแแฅแขแแ แแแ, แคแแแแแแแแ, แกแแแฃแจแแ แฏแแฃแคแแแ... - แ แแกแแช แแฅแแแ แฃแฌแแแแแ แแแ.
แแแ แแแแ, แแแแแ แจแแแฅแแแแ แฉแแแแ "แฎแ" 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;
แแแแแฌแงแแ แฃแแแ แขแแแแกแ แแแแชแแแแแแ - แงแแแแ แแแแแแจแ แแแแแก แแแแแ, แ แแแแแแช แแฃแจแแแแก แแแแแ แแขแฃแ แกแแฅแขแแ แจแ, แแ แแแ แแ แฅแแแก แแแแแกแแแ แแกแแ - แแแแแแแ แแแแแซแแก แงแแแแ แจแแแแ. แแกแแแ แแแ แแ แแฅแแแแแแ แจแแแแแแแแแแแแก โแกแแฆแ แแแกโ แแแฆแแแ... แแก แงแแแแแคแแ แ แจแแกแแซแแแ แกแแญแแ แ แแงแแก, แแแแแแแแแ, แ แแแแ แกแแฎแแก แแกแแจแแแแแแแ.
แงแแแแแคแแ แ แแแ แแแ แแฅแแแแ, แแฃ แแ แจแแแแแแแแแแแแก แแฎแแแแ แแ แ แแแแ แแฅแแแแ แแ แ แแชแฎแแ แแแแฃแแจแแ, แแแแ แแ แแฃ 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
แแ แจแแแแแฎแแแแแกแแแแก แฉแแแ แแแแแแแงแแแแ แขแแแแฃแ แ แ แแแฃแ แกแแฃแแ JOIN:
แชแฎแแแแ, แแ แแแแฎแแแแแก แแแแแแแ แแแแแแ แแแแแแก แ แแแแแแแแ แแแแฎแแแแ แจแแแแแแแแแแแแก แกแแแ แแ แ แแแแแแแแแก (แแ แแแแแแ แ แแแแแแแแ แแแแฃแแแ) แแ แแแแก แจแแแซแแแแ แแแกแญแแ แแแก แกแแแแแแ แแแแจแแแแแแแแแ แ แแกแฃแ แกแแแ แแ, แจแแแแแแ, แแ แ.
แแแแแ แจแแแแแแฌแแแ "แงแแแแแแ แคแแ แแ" แฅแแแฎแ:
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 แซแแแแ แแแแแฅแกแจแ. แจแแกแแซแแแแแแแ แแฃ แแ แ แแแแแแแแก แแแแแแแแ?
แแแงแแ แ แแแ แแฅแขแแ แแแ แแแแแฅแกแแ
แแแญแแ แแแแ แแฃ แแ แ แชแแแแ แแแแแฅแกแแก แแแแฎแแแแ แแแแแแฃแแ แแแแแซแแกแแแแก? แแแแแแแก, แ แแ แแ แ - แฉแแแ แจแแแแแซแแแ แฌแแแแแแแฎแแ แแแแแฅแกแแแแ แแ แแแ แแฃแแแ แ แแแแแแแแ แแแแแแจแแก แแแแแงแแแแแ แแ แ แแแ แแ via = ANY(array)
.
แแแแแขแแคแแแแขแแ แแแแก แแแแแแฃแ แแกแแ แฏแแฃแคแจแ แฉแแแ แจแแแแแซแแแ แแแแฆแแ แฌแแแ แแขแแแแ แแแแแแแ แงแแแแ ID-แแแ "แแแแแซแแแแก" แแแฎแแแแแ. แแแฃ, แงแแแแ แแแแแแแแ แแขแแแแ แฉแแแ แแแแแแแแแแ แแแซแแแแแ แแแ แแแแฃแแ แแแแแก แงแแแแ แจแแแแแแแแแแ แแ แแแ แแฃแแแ.
แแฎแแแแ แแฅ แแ แแก แแ แแแแแแ, แ แแแฃแ แกแแฃแแ แจแแ แฉแแแแกแแก, แแฅแแแ แแแ แจแแซแแแแ แกแแแฃแแแ แแแแก แฌแแแแแแก แฌแงแแแแ แแแแฎแแแแแจแ, แแแแ แแ แฉแแแ แ แแแแ แแ แฃแแแ แจแแแแ แฉแแแ แแฎแแแแ แแก, แ แแช แฌแแแ แแแแแแ แแงแ แแแแแแแ... แแแแแแแก, แ แแ แจแแฃแซแแแแแแแ แฌแงแแแแแ แแแแฎแแแแแก แแแแแแแแ แแแแแ แกแแแแฅแชแแแกแแแแก, แแแแ แแ แแแกแ แแแแแ แแขแฃแแ แแแแแกแแแแก แจแแกแแซแแแแแแแ. แแ แแก แแแแ แแกแแแ แจแแแซแแแแ แแงแแก แแแกแแแ - แ แแช แฃแแแ แแแแแแแงแแแแ 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-แฏแแ แแ แแจแแแ แ แแ แฉแแแ แแแแแแแแแแ แแแแแแแ แแฃแคแแ แ, แ แแแแแ แฉแแแ แแแแฅแแก แแฎแแแแ 5 แแแ แ แแแแแฅแกแจแ 30-แแก แแแชแแแแ!
แแแแแขแแแแแ แแแแฃแกแ แแ แแก แแก แคแแฅแขแ, แ แแ แกแแแแแแ แแแแฆแแแแก แจแแแแแ, แแแแแขแแคแแแแขแแ แแแ แแแ แฉแแแ แแแฌแแกแ แแแแแฃแแ "แแแแแแแแก" แแแฎแแแแแ.
แแแแแซแแก แแแจแแแ
แจแแแแแแ แแแกแแแ แแแ, แ แแแแแแช แฎแแแก แจแแฃแฌแงแแแก แแฃแจแแแแแก แแแฃแแฏแแแแกแแแแก แแ แแก - "แคแแแแแแก" แแ แจแแฃแซแแแแ แจแแแแแแแก แแแฉแแแ, แแแฃ แแแแแแแก แกแฃแแแช แแ แแ แแก แกแแญแแ แ โแฅแแแแแแแโ แงแฃแ แแแ. แฉแแแแ แแแแชแแแแก แคแแ แแฃแแแ แแแแจแ แแก แแแจแแแแก, แ แแ แแฃ แฉแแแ แแแแงแแแแแ แแแแงแแคแแแแแแแแก แฏแแญแแก แแ แแแแแฆแฌแแแ แแแแแแจแ แแแแแก, แแแจแแ แแ แแ แแก แกแแญแแ แ แแ แคแแแแแแแก แแแกแฌแแ แแ แฃแคแ แ แจแแ แก แงแฃแ แแแ.
แแแแแ แจแแแแแแ แฉแแแแก แแแแแแแแ แแแแแขแแแแแ 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 ะผั.
แแแแ! แแแแแแแก, แ แแ แงแแแแ แฎแแก แแแแแแแขแแแแก แแฎแแแแ 30%-แแ แชแแขแ แแแขแก แฐแงแแแก แจแแแแแแแแแแแ.
แแฎแแ แแแแแ แแแแแแแงแแแแ แแแแแ แแแแกแฎแแแแแแฃแแ แแแฅแแแแแ - แแแแจแแ แแแ แ แแแฃแ แกแแฃแ แแแฌแแแแแ แแแจแแแแแแ LATERAL
, แ แแแแแแช แกแแจแฃแแแแแแก แแแแแชแแแก แแแฃแงแแแแแแแแ แจแแแแแแ แ แแแฃแ แกแแฃแแ โแชแฎแ แแแแกโ แแแแแแแ แแ แแแแแแแงแแแแ แแแ แแแแขแฃแแ แคแฃแแฅแชแแ แคแแแขแ แแชแแแก แแแ แแแแ แแแแแซแแ แแแคแฃแซแแแแฃแแ แแแกแแฆแแแแแแก แแแแ แแแแก แจแแกแแแชแแ แแแแแ:
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. แแแแฃแแ แฃแแแแ แคแแกแแแแก
แแก แแแแแ แแแแ แแแแแแแแแแแแ, แแฃ แแฅแแแ แฃแแแ แจแแแแ แแแแ แฉแแแแฌแแ แแแ แงแแแแ แแแแแแแขแแกแแแแก โแฎแแแ แแแฆแแโ, แฎแแแ แจแแแแแ แฉแฃแแแ แแแคแแ แแแชแแ แแแแก แจแแกแแฎแแ, แแฃ แ แแแแแ แฌแงแแ แแก แคแฃแ แชแแแ (แแ แ แ แแแแแแแขแแ แแแแ) แแแแแแฌแแแ แแแแฃแจแจแ แแแกแ แฉแแ แแแ - แแแแแแแแแ, แจแแแแฏแแแแแแแ แแแแแ แแจแแก แแแแแ แแ แแแ. แแแแแซแแแแ แแแแ แแแแแแแแ.
แจแแแแแแ, แฃแแแ แแฅแแแก แแแฆแแแฃแแ แแฎแแแแ, แ แแแแ แช แแแแชแแคแชแแแก แแแแแแแกแขแฃแ แแแแแ แกแแแฃแแ, แ แแแแแ แแแแฎแแแแ แแฆแแแฉแแแแแ แซแแแแแ แ แแฃแแ. แแแแ แแ แแฃ แแก แแแแแแแ แแแก แแฅแแแแก แแแแแชแแแแ แแแแแจแ, แฃแแแ แแคแแฅแ แแ แแกแแแแกแ แขแแฅแแแแแก แแแแแงแแแแแแแ.
แแแแแฌแงแแ แ แแแแแแแแ แแแ แขแแแ แแแแชแฎแแแแแแ:
- แแแแแ แฉแแแแฌแแ แ แแแแแชแแแแ แแแแแแแ แฏแแแแ แแ แแฎแแ แฌแแแแแแฎแ.
- แฉแแแแฌแแ แแแ แแแแแชแแแแ แแแแแแแ แฏแแฃแคแฃแ แแ แฌแแแแแฎแแ แฃแคแ แ แแคแแฅแขแฃแ แแแแแแ แ แแแ แขแ.
แแฎแแ แจแแแแชแแแแ แจแแแฅแแแแ แกแแญแแ แ แแแแฎแแแแ.
แแแแแฏแ 1
แชแฎแแแแ, แ แแแฃแ แกแแแก แแแแชแแแแแแแชแแแกแแก (แกแแ แแแฅแแแแแแแ แแแก แแแ แแจแ!) แฃแแแ แแแแแแแแแแ แแแแแ แคแแแแแแแก แฉแแแแฌแแ แแแ แกแแฌแงแแกแ แแแแแขแแคแแแแขแแ แแแแก แกแแแ แแแแแก แกแแคแฃแซแแแแแ:
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
...
แแฃ แแแแแแก แฃแชแแแฃแ แแ แแแแฉแแแแ, แ แแ "แแแแแแแฅแขแ" แแแแฎแแแ แ แแแแ แช แกแขแ แแฅแแแ แแ แแ แ แแแกแแแ, แแแจแแ แแแแก แแแ แขแแแ แแฎแกแแ แแ แกแแแแแก. แกแขแ แแแแแแแกแแแแก แแ แแก แฉแแจแแแแแฃแแ แแแ แแแแชแแแก โแฌแแแแแแแแแกโ แคแฃแแฅแชแแ string_agg
, แแแแ แแ แแ แ แแแกแแแแแแกแแแแก. แแแฃแฎแแแแแแ แแแแกแ, แ แแ แแก
แแแแแฏแ 2
แแฎแแ แฉแแแ แแแแแฆแแแ แแแแงแแคแแแแแแก ID-แแแแก แแแแแแแฅแขแก, แ แแแแแแช แจแแแแแแ แฌแแแแแฎแแแก แกแแญแแ แแแแก. แแแแฅแแแก แงแแแแแแแแก แแกแแแ แแฅแแแแ แแฃแแแแ แแแฃแแ แแ แแแแแแแฃแ แ แแแแ แแแแก แกแฎแแแแแกแฎแแ แฉแแแแฌแแ แแแจแ - แแกแ แแแแแฅแชแแแแ แแแแฏแแฃแคแ แแกแแแ, แฌแงแแ แแก แคแแแแแแแก แจแแกแแฎแแ แแแคแแ แแแชแแแก แจแแแแ แฉแฃแแแแแกแแก.
แแแแ แแ แแฅ แกแแแ แฃแแแแฃแ แแแ แแแแแแแแแ:
- แแแแฎแแแแแก "แกแฃแแแฃแ แกแแฃแแ" แแแฌแแแ แแ แจแแแซแแแแ แจแแแชแแแแแก แแแ แแแแขแฃแ แคแฃแแฅแชแแแแก
GROUP BY
. - แ แแแฃแ แกแแฃแ โแชแฎแ แแแแโ แแแแแแแแ แแ แจแแแซแแแแ แแงแแก แฉแแแแแฃแ แฅแแแแแแฎแแแแแจแ.
- แแแแฎแแแแ แ แแแฃแ แกแแฃแ แแแฌแแแจแ แแ แจแแแซแแแแ แจแแแชแแแแแก CTE-แก.
แกแแแแแแแแ แแ, แงแแแแ แแ แแ แแแแแแแก แแแแแแ แแแ แกแแแแแแ แแแ แขแแแแ. แแแแแฌแงแแ แแแแแแแ.
CTE แ แแแฃแ แกแแฃแ แแแฌแแแจแ
แแฅ แแกแ แแ แแ แแก แแฃแจแแแแก:
WITH RECURSIVE tree AS (
...
UNION ALL
WITH T (...)
SELECT ...
)
แแ แแกแ แแฃแจแแแแก, แคแ แฉแฎแแแแแ แฅแแแแก แแแแกแฎแแแแแแแก!
WITH RECURSIVE tree AS (
...
UNION ALL
(
WITH T (...)
SELECT ...
)
)
แฉแแแแแฃแแ แแแแฎแแแแ แ แแแฃแ แกแแฃแแ โแชแฎแ แแแแกโ แฌแแแแแฆแแแแ
แฐแ... แ แแแฃแ แกแแฃแ CTE-แแ แฌแแแแแ แจแแฃแซแแแแแแแ แฅแแแแแแฎแแแแแจแ. แแแแ แแ แแก แจแแแซแแแแ แแงแแก CTE แจแแแแแ! แแ แฉแแแแแฃแ แแแแฎแแแแแก แฃแแแ แจแแฃแซแแแ แแ CTE-แแ แฌแแแแแ!
GROUP BY แจแแแ แ แแแฃแ แกแแแก แแแฎแแแแแ
แฃแกแแแแแแแแ, แแแแ แแ... แฉแแแ แแแแฅแแก GROUP BY-แแก แแแฃแแแชแแแก แแแ แขแแแ แแแ 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
แคแแแแแแกแแแแก แแ แแคแแ แ แแแแแ แฉแแแแ:
- แฉแแแ แแแแแฎแฃแแแแ โแกแแฅแชแแแแแกโ แฉแแแแฌแแ แแแก แแแฏแแฃแคแแแฃแแ ID-แแแแก แแแแ แแแแก แกแแคแฃแซแแแแแ
- แฉแแแ แแแแแ แแแ แแแแแแแแแฃแ แแแแแแแแแแแก แแ แแแแแแแฃแ แ แคแฃแ แชแแแแแก โแแแแแแแฅแขแแแกโ.
- "แแแคแแ แแแแแ" set-string แแแแแงแแแแแแ
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