เชเชเชฟเชฒ ERP เชธเชฟเชธเซเชเชฎเซเชฎเชพเช เชเชฃเซ เชธเชเชธเซเชฅเชพเช เชตเชเชถเชตเซเชฒเซ เชธเซเชตเชญเชพเชต เชงเชฐเชพเชตเซ เชเซเชเซเชฏเชพเชฐเซ เชธเชเชพเชคเซเชฏ เชตเชธเซเชคเซเช เช เชเชฆเชฐ เชเชตเซ เชเซ เชชเซเชฐเซเชตเช-เชตเชเชถเช เชธเชเชฌเชเชงเซเชจเซเช เชตเซเชเซเชท - เช เชเชจเซเชเชฐเชชเซเชฐเชพเชเชเชจเซเช เชธเชเชเช เชจเชพเชคเซเชฎเช เชฎเชพเชณเชเซเช เชเซ (เช เชคเชฎเชพเชฎ เชถเชพเชเชพเช, เชตเชฟเชญเชพเชเซ เช เชจเซ เชเชพเชฐเซเชฏ เชเซเชฅเซ), เช เชจเซ เชฎเชพเชฒเชจเซ เชธเซเชเชฟ, เช เชจเซ เชเชพเชฐเซเชฏเชจเชพ เชเซเชทเซเชคเซเชฐเซ, เช เชจเซ เชตเซเชเชพเชฃ เชฌเชฟเชเชฆเซเชเชจเซ เชญเซเชเซเชณ,...
เชนเชเซเชเชคเชฎเชพเช, เชคเซเชฏเชพเช เชเซเช เชจเชฅเซ
เชกเซเชฌเซเชเชฎเชเชธเชฎเชพเช เชเชตเชพ เชตเซเชเซเชทเชจเซ เชธเชเชเซเชฐเชนเชฟเชค เชเชฐเชตเชพเชจเซ เชเชฃเซ เชฐเซเชคเซ เชเซ, เชชเชฐเชเชคเซ เชเชเซ เชเชชเชฃเซ เชซเชเซเชค เชเช เชตเชฟเชเชฒเซเชช เชชเชฐ เชงเซเชฏเชพเชจ เชเซเชจเซเชฆเซเชฐเชฟเชค เชเชฐเซเชถเซเช:
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
เช เชชเซเชฐเชถเซเชจเซ เชฎเชพเชเซ เช
เชฎเซ เชฒเชพเชเซเชทเชฃเชฟเชเชจเซ เชเชชเชฏเซเช เชเชฐเซเชฏเซ เชชเซเชจเชฐเชพเชตเชฐเซเชคเชฟเชค เชเซเชกเชพเช:
เชฆเซเชเซเชคเซ เชฐเซเชคเซ, เช เชตเชฟเชจเชเชคเซ เชฎเซเชกเซเชฒ เชธเชพเชฅเซ เชชเซเชจเชฐเชพเชตเชฐเซเชคเชจเซเชจเซ เชธเชเชเซเชฏเชพ เชตเชเชถเชเซเชจเซ เชเซเชฒ เชธเชเชเซเชฏเชพ เชธเชพเชฅเซ เชฎเซเชณ เชเชพเชถเซ (เช
เชจเซ เชคเซเชฎเชพเชเชจเชพ เชเชฃเชพ เชกเชเชจ เชเซ), เช
เชจเซ เช เชเซเชฌ เชจเซเชเชงเชชเชพเชคเซเชฐ เชธเชเชธเชพเชงเชจเซ เชฒเช เชถเชเซ เชเซ, เช
เชจเซ เชชเชฐเชฟเชฃเชพเชฎเซ, เชธเชฎเชฏ.
เชเชพเชฒเซ "เชธเซเชฅเซ เชชเชนเซเชณเชพ" เชธเชฌเชเซเชฐเซ เชชเชฐ เชคเชชเชพเชธ เชเชฐเซเช:
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 เชถเซเชง เชชเชฃ เชเชฐเซ. เชถเซเช เชเชเซเช เชเชฐเชตเซเช เชถเชเซเชฏ เชเซ?
เชเชจเซเชกเซเชเซเชธ เชฆเซเชตเชพเชฐเชพ เชฌเชฒเซเช เชชเซเชฐเซเชซเชฐเซเชกเชฟเชเช
เชถเซเช เชเชชเชฃเซ เชฆเชฐเซเช เชจเซเชก เชฎเชพเชเซ เช
เชฒเช เชเชจเซเชกเซเชเซเชธ เชเซเชตเซเชฐเซ เชเชฐเชตเชพเชจเซ เชเชฐเซเชฐ เชเซ? เชคเซ เชคเชพเชฐเชฃ เชเชชเซ เชเซ เชเซ เชจเชพ - เช
เชฎเซ เช
เชจเซเชเซเชฐเชฎเชฃเชฟเชเชพเชฎเชพเชเชฅเซ เชตเชพเชเชเซ เชถเชเซเช เชเซเช เชเช เชเซเชฒเชฎเชพเช เชเช เชธเชพเชฅเซ เช
เชจเซเช เชเซเชจเซ เชเชชเชฏเซเช เชจเซ เชฎเชฆเชฆ เชธเชพเชฅเซ = 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 เชจเซ เชเชชเชฏเซเช เชเชฐเซเชจเซ เช
เชจเซเชเชฐเชฃ เชเชฐเชตเชพเชจเซ เชเช เชธเชฐเชณ เชฐเซเชค เชเซ 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 เชจเชพ เชธเชฎเซเชนเชจเชพ เชเชงเชพเชฐเซ "เชตเชฟเชญเชพเช" เชฐเซเชเซเชฐเซเชก เชตเชพเชเชเซเช เชเซเช
- เช เชฎเซ เชฌเชพเชฆเชฌเชพเชเซ เชเชฐเซเชฒ เชตเชฟเชญเชพเชเซเชจเซ เชคเซเชฒเชจเชพ เชฎเซเชณ เชถเซเชเซเชธเชจเชพ "เชธเซเชเซเชธ" เชธเชพเชฅเซ เชเชฐเซเช เชเซเช
- เชจเซ เชเชชเชฏเซเช เชเชฐเซเชจเซ เชธเซเช-เชธเซเชเซเชฐเชฟเชเชเชจเซ "เชตเชฟเชธเซเชคเซเชค เชเชฐเซ".
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