PostgreSQL เจเจ‚เจŸเฉ€เจชเฉˆเจŸเจฐเจจ: เจ–เจฐเจ—เฉ‹เจธเจผ เจฆเจพ เจฎเฉ‹เจฐเฉ€ เจ•เจฟเฉฐเจจเจพ เจกเฉ‚เฉฐเจ˜เจพ เจนเฉˆ? เจ†เจ“ เจฒเฉœเฉ€เจตเจพเจฐ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจฒเฉฐเจ˜เฉ€เจ

เจ—เฉเฉฐเจเจฒเจฆเจพเจฐ ERP เจชเฉเจฐเจฃเจพเจฒเฉ€เจ†เจ‚ เจตเจฟเฉฑเจš เจฌเจนเฉเจค เจธเจพเจฐเฉ€เจ†เจ‚ เจธเฉฐเจธเจฅเจพเจตเจพเจ‚ เจฆเฉ€ เจฒเฉœเฉ€เจตเจพเจฐ เจชเฉเจฐเจ•เจฟเจฐเจคเฉ€ เจนเฉเฉฐเจฆเฉ€ เจนเฉˆเจœเจฆเฉ‹เจ‚ เจธเจฎเจฐเฉ‚เจช เจตเจธเจคเฉ‚เจ†เจ‚ เจฒเจพเจˆเจจ เจตเจฟเฉฑเจš เจฒเฉฑเจ—เจฆเฉ€เจ†เจ‚ เจนเจจ เจชเฉ‚เจฐเจตเจœ-เจตเฉฐเจธเจผ เจฆเฉ‡ เจฐเจฟเจธเจผเจคเฉ‡ เจฆเจพ เจฐเฉเฉฑเจ– - เจ‡เจน เจเจ‚เจŸเจฐเจชเฉเจฐเจพเจˆเจœเจผ เจฆเจพ เจธเฉฐเจ—เจ เจจเจพเจคเจฎเจ• เจขเจพเจ‚เจšเจพ เจนเฉˆ (เจ‡เจน เจธเจพเจฐเฉ€เจ†เจ‚ เจธเจผเจพเจ–เจพเจตเจพเจ‚, เจตเจฟเจญเจพเจ— เจ…เจคเฉ‡ เจ•เฉฐเจฎ เจธเจฎเฉ‚เจน), เจ…เจคเฉ‡ เจฎเจพเจฒ เจฆเฉ€ เจธเฉ‚เจšเฉ€, เจ…เจคเฉ‡ เจ•เฉฐเจฎ เจฆเฉ‡ เจ–เฉ‡เจคเจฐเจพเจ‚, เจ…เจคเฉ‡ เจตเจฟเจ•เจฐเฉ€ เจฌเจฟเฉฐเจฆเฉ‚เจ†เจ‚ เจฆเจพ เจญเฉ‚เจ—เฉ‹เจฒ, ...

PostgreSQL เจเจ‚เจŸเฉ€เจชเฉˆเจŸเจฐเจจ: เจ–เจฐเจ—เฉ‹เจธเจผ เจฆเจพ เจฎเฉ‹เจฐเฉ€ เจ•เจฟเฉฐเจจเจพ เจกเฉ‚เฉฐเจ˜เจพ เจนเฉˆ? เจ†เจ“ เจฒเฉœเฉ€เจตเจพเจฐ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจฒเฉฐเจ˜เฉ€เจ

เจตเจพเจธเจคเจต เจตเจฟเฉฑเจš, เจ•เฉ‹เจˆ เจตเฉ€ เจจเจนเฉ€เจ‚ เจนเฉˆ เจตเจชเจพเจฐ เจ†เจŸเฉ‹เจฎเฉ‡เจธเจผเจจ เจ–เฉ‡เจคเจฐ, เจœเจฟเฉฑเจฅเฉ‡ เจจเจคเฉ€เจœเฉ‡ เจตเจœเฉ‹เจ‚ เจ•เฉ‹เจˆ เจฆเจฐเจœเจพเจฌเฉฐเจฆเฉ€ เจจเจนเฉ€เจ‚ เจนเฉ‹เจตเฉ‡เจ—เฉ€เฅค เจชเจฐ เจญเจพเจตเฉ‡เจ‚ เจคเฉเจธเฉ€เจ‚ "เจ•เจพเจฐเฉ‹เจฌเจพเจฐ เจฒเจˆ" เจ•เฉฐเจฎ เจจเจนเฉ€เจ‚ เจ•เจฐเจฆเฉ‡ เจนเฉ‹, เจคเจพเจ‚ เจตเฉ€ เจคเฉเจธเฉ€เจ‚ เจ†เจธเจพเจจเฉ€ เจจเจพเจฒ เจฒเฉœเฉ€เจตเจพเจฐ เจธเจฌเฉฐเจงเจพเจ‚ เจฆเจพ เจธเจพเจนเจฎเจฃเจพ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹เฅค เจ‡เจน เจคเจฟเฉฑเจ–เจพ เจนเฉˆ, เจ‡เฉฑเจฅเฉ‹เจ‚ เจคเฉฑเจ• เจ•เจฟ เจคเฉเจนเจพเจกเฉ‡ เจชเจฐเจฟเจตเจพเจฐเจ• เจฐเฉเฉฑเจ– เจœเจพเจ‚ เจธเจผเจพเจชเจฟเฉฐเจ— เจธเฉˆเจ‚เจŸเจฐ เจตเจฟเฉฑเจš เจ‡เจฎเจพเจฐเจค เจฆเฉ€ เจซเจฒเฉ‹เจฐ เจฏเฉ‹เจœเจจเจพ เจตเฉ€ เจ‡เฉฑเจ•เฉ‹ เจœเจฟเจนเฉ€ เจฌเจฃเจคเจฐ เจนเฉˆเฅค

DBMS เจตเจฟเฉฑเจš เจ…เจœเจฟเจนเฉ‡ เจฐเฉเฉฑเจ– เจจเฉ‚เฉฐ เจธเจŸเฉ‹เจฐ เจ•เจฐเจจ เจฆเฉ‡ เจฌเจนเฉเจค เจธเจพเจฐเฉ‡ เจคเจฐเฉ€เจ•เฉ‡ เจนเจจ, เจชเจฐ เจ…เฉฑเจœ เจ…เจธเฉ€เจ‚ เจธเจฟเจฐเจซ เจ‡เฉฑเจ• เจตเจฟเจ•เจฒเจช 'เจคเฉ‡ เจงเจฟเจ†เจจ เจ•เฉ‡เจ‚เจฆเจฐเจค เจ•เจฐเจพเจ‚เจ—เฉ‡:

CREATE TABLE hier(
  id
    integer
      PRIMARY KEY
, pid
    integer
      REFERENCES hier
, data
    json
);

CREATE INDEX ON hier(pid); -- ะฝะต ะทะฐะฑั‹ะฒะฐะตะผ, ั‡ั‚ะพ FK ะฝะต ะฟะพะดั€ะฐะทัƒะผะตะฒะฐะตั‚ ะฐะฒั‚ะพัะพะทะดะฐะฝะธะต ะธะฝะดะตะบัะฐ, ะฒ ะพั‚ะปะธั‡ะธะต ะพั‚ PK

เจ…เจคเฉ‡ เจœเจฆเฉ‹เจ‚ เจคเฉเจธเฉ€เจ‚ เจฒเฉœเฉ€ เจฆเฉ€ เจกเฉ‚เฉฐเจ˜เจพเจˆ เจตเจฟเฉฑเจš เจเจพเจค เจฎเจพเจฐ เจฐเจนเฉ‡ เจนเฉ‹, เจคเจพเจ‚ เจ‡เจน เจงเฉ€เจฐเจœ เจจเจพเจฒ เจ‡เจน เจฆเฉ‡เจ–เจฃ เจฒเจˆ เจ‰เจกเฉ€เจ• เจ•เจฐ เจฐเจฟเจนเจพ เจนเฉˆ เจ•เจฟ เจ…เจœเจฟเจนเฉ‡ เจขเจพเจ‚เจšเฉ‡ เจจเจพเจฒ เจ•เฉฐเจฎ เจ•เจฐเจจ เจฆเฉ‡ เจคเฉเจนเจพเจกเฉ‡ "เจญเฉ‹เจฒเฉ‡" เจคเจฐเฉ€เจ•เฉ‡ เจ•เจฟเฉฐเจจเฉ‡ เจชเฉเจฐเจญเจพเจตเจธเจผเจพเจฒเฉ€ เจนเฉ‹เจฃเจ—เฉ‡เฅค

PostgreSQL เจเจ‚เจŸเฉ€เจชเฉˆเจŸเจฐเจจ: เจ–เจฐเจ—เฉ‹เจธเจผ เจฆเจพ เจฎเฉ‹เจฐเฉ€ เจ•เจฟเฉฐเจจเจพ เจกเฉ‚เฉฐเจ˜เจพ เจนเฉˆ? เจ†เจ“ เจฒเฉœเฉ€เจตเจพเจฐ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจฒเฉฐเจ˜เฉ€เจ
เจ†เจ‰ เจ†เจฎ เจธเจฎเฉฑเจธเจฟเจ†เจตเจพเจ‚ เจจเฉ‚เฉฐ เจตเฉ‡เจ–เฉ€เจ เจœเฉ‹ เจชเฉˆเจฆเจพ เจนเฉเฉฐเจฆเฉ€เจ†เจ‚ เจนเจจ, เจ‰เจนเจจเจพเจ‚ เจจเฉ‚เฉฐ SQL เจตเจฟเฉฑเจš เจฒเจพเจ—เฉ‚ เจ•เจฐเจจเจพ, เจ…เจคเฉ‡ เจ‰เจนเจจเจพเจ‚ เจฆเฉ€ เจ•เจพเจฐเจ—เฉเจœเจผเจพเจฐเฉ€ เจตเจฟเฉฑเจš เจธเฉเจงเจพเจฐ เจ•เจฐเจจ เจฆเฉ€ เจ•เฉ‹เจธเจผเจฟเจธเจผ เจ•เจฐเฉ‹เฅค

#1เฅค เจ–เจฐเจ—เฉ‹เจธเจผ เจฆเจพ เจฎเฉ‹เจฐเฉ€ เจ•เจฟเฉฐเจจเจพ เจกเฉ‚เฉฐเจ˜เจพ เจนเฉˆ?

เจ†เจ“, เจจเจฟเจธเจผเจšเจฟเจคเจคเจพ เจฒเจˆ, เจ‡เจน เจธเจตเฉ€เจ•เจพเจฐ เจ•เจฐเฉ€เจ เจ•เจฟ เจ‡เจน เจขเจพเจ‚เจšเจพ เจธเฉฐเจ—เจ เจจ เจฆเฉ‡ เจขเจพเจ‚เจšเฉ‡ เจตเจฟเฉฑเจš เจตเจฟเจญเจพเจ—เจพเจ‚ เจฆเฉ€ เจ…เจงเฉ€เจจเจคเจพ เจจเฉ‚เฉฐ เจฆเจฐเจธเจพเจ‰เจ‚เจฆเจพ เจนเฉˆ: เจตเจฟเจญเจพเจ—, เจตเฉฐเจก, เจธเฉˆเจ•เจŸเจฐ, เจธเจผเจพเจ–เจพเจตเจพเจ‚, เจ•เจพเจฐเจœ เจธเจฎเฉ‚เจน... - เจœเฉ‹ เจตเฉ€ เจคเฉเจธเฉ€เจ‚ เจ‰เจนเจจเจพเจ‚ เจจเฉ‚เฉฐ เจ•เจนเจฟเฉฐเจฆเฉ‡ เจนเฉ‹เฅค
PostgreSQL เจเจ‚เจŸเฉ€เจชเฉˆเจŸเจฐเจจ: เจ–เจฐเจ—เฉ‹เจธเจผ เจฆเจพ เจฎเฉ‹เจฐเฉ€ เจ•เจฟเฉฐเจจเจพ เจกเฉ‚เฉฐเจ˜เจพ เจนเฉˆ? เจ†เจ“ เจฒเฉœเฉ€เจตเจพเจฐ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจฒเฉฐเจ˜เฉ€เจ

เจชเจนเจฟเจฒเจพเจ‚, เจ†เจ“ 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;

เจ†เจ‰ เจธเจญ เจคเฉ‹เจ‚ เจธเจฐเจฒ เจ•เฉฐเจฎ เจจเจพเจฒ เจธเจผเฉเจฐเฉ‚ เจ•เจฐเฉ€เจ - เจ‰เจนเจจเจพเจ‚ เจธเจพเจฐเฉ‡ เจ•เจฐเจฎเจšเจพเจฐเฉ€เจ†เจ‚ เจจเฉ‚เฉฐ เจฒเฉฑเจญเจฃเจพ เจœเฉ‹ เจ•เจฟเจธเฉ‡ เจ–เจพเจธ เจธเฉˆเจ•เจŸเจฐ เจตเจฟเฉฑเจš เจ•เฉฐเจฎ เจ•เจฐเจฆเฉ‡ เจนเจจ, เจœเจพเจ‚ เจฒเฉœเฉ€ เจฆเฉ‡ เจฐเฉ‚เจช เจตเจฟเฉฑเจš - เจ‡เฉฑเจ• เจจเฉ‹เจก เจฆเฉ‡ เจธเจพเจฐเฉ‡ เจฌเฉฑเจšเจฟเจ†เจ‚ เจจเฉ‚เฉฐ เจฒเฉฑเจญเฉ‹. เจตเฉฐเจธเจผเจœ เจฆเฉ€ "เจกเฉ‚เฉฐเจ˜เจพเจˆ" เจจเฉ‚เฉฐ เจชเฉเจฐเจพเจชเจค เจ•เจฐเจจเจพ เจตเฉ€ เจšเฉฐเจ—เจพ เจนเฉ‹เจตเฉ‡เจ—เจพ... เจ‡เจน เจธเจญ เจ•เฉเจ เจœเจผเจฐเฉ‚เจฐเฉ€ เจนเฉ‹ เจธเจ•เจฆเจพ เจนเฉˆ, เจ‰เจฆเจพเจนเจฐเจจ เจฒเจˆ, เจ•เจฟเจธเฉ‡ เจ•เจฟเจธเจฎ เจฆเฉ€ เจ‰เจธเจพเจฐเฉ€ เจฒเจˆ เจ‡เจนเจจเจพเจ‚ เจ•เจฐเจฎเจšเจพเจฐเฉ€เจ†เจ‚ เจฆเฉ€ IDs เจฆเฉ€ เจธเฉ‚เจšเฉ€ เจฆเฉ‡ เจ…เจงเจพเจฐ เจคเฉ‡ เจ—เฉเฉฐเจเจฒเจฆเจพเจฐ เจšเฉ‹เจฃ.

เจธเจญ เจ•เฉเจ เจ เฉ€เจ• เจนเฉ‹เจตเฉ‡เจ—เจพ เจœเฉ‡เจ•เจฐ เจ‡เจนเจจเจพเจ‚ เจตเฉฐเจธเจผเจœเจพเจ‚ เจฆเฉ‡ เจธเจฟเจฐเจซ เจฆเฉ‹ เจชเฉฑเจงเจฐ เจนเจจ เจ…เจคเฉ‡ เจ—เจฟเจฃเจคเฉ€ เจ‡เฉฑเจ• เจฆเจฐเจœเจจ เจฆเฉ‡ เจ…เฉฐเจฆเจฐ เจนเฉˆ, เจชเจฐ เจœเฉ‡เจ•เจฐ 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

เจ‡เจนเจจเจพเจ‚ เจธเจตเจพเจฒเจพเจ‚ เจฒเจˆ เจ…เจธเฉ€เจ‚ เจ†เจฎ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เฉ€เจคเฉ€ เจนเฉˆ เจ†เจตเจฐเจคเฉ€ เจœเฉเฉœเฉ‹:
PostgreSQL เจเจ‚เจŸเฉ€เจชเฉˆเจŸเจฐเจจ: เจ–เจฐเจ—เฉ‹เจธเจผ เจฆเจพ เจฎเฉ‹เจฐเฉ€ เจ•เจฟเฉฐเจจเจพ เจกเฉ‚เฉฐเจ˜เจพ เจนเฉˆ? เจ†เจ“ เจฒเฉœเฉ€เจตเจพเจฐ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจฒเฉฐเจ˜เฉ€เจ

เจธเจชเฉฑเจธเจผเจŸ เจนเฉˆ, เจ‡เจธ เจฌเฉ‡เจจเจคเฉ€ เจฎเจพเจกเจฒ เจฆเฉ‡ เจจเจพเจฒ เจฆเฉเจนเจฐเจพเจ“ เจฆเฉ€ เจธเฉฐเจ–เจฟเจ† เจ”เจฒเจพเจฆ เจฆเฉ€ เจ•เฉเฉฑเจฒ เจธเฉฐเจ–เจฟเจ† เจจเจพเจฒ เจฎเฉ‡เจฒ เจ–เจพเจ‚เจฆเฉ€ เจนเฉˆ (เจ…เจคเฉ‡ เจ‰เจนเจจเจพเจ‚ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจ•เจˆ เจฆเจฐเจœเจจ เจนเจจ), เจ…เจคเฉ‡ เจ‡เจน เจ•เจพเจซเจผเฉ€ เจฎเจนเฉฑเจคเจตเจชเฉ‚เจฐเจจ เจธเจฐเฉ‹เจค เจฒเฉˆ เจธเจ•เจฆเจพ เจนเฉˆ, เจ…เจคเฉ‡ เจจเจคเฉ€เจœเฉ‡ เจตเจœเฉ‹เจ‚, เจธเจฎเจพเจ‚เฅค

เจ†เจ‰ "เจธเจญ เจคเฉ‹เจ‚ เจšเฉŒเฉœเฉ€" เจธเจฌเจŸเฉเจฐเฉ€ เจฆเฉ€ เจœเจพเจ‚เจš เจ•เจฐเฉ€เจ:

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;

PostgreSQL เจเจ‚เจŸเฉ€เจชเฉˆเจŸเจฐเจจ: เจ–เจฐเจ—เฉ‹เจธเจผ เจฆเจพ เจฎเฉ‹เจฐเฉ€ เจ•เจฟเฉฐเจจเจพ เจกเฉ‚เฉฐเจ˜เจพ เจนเฉˆ? เจ†เจ“ เจฒเฉœเฉ€เจตเจพเจฐ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจฒเฉฐเจ˜เฉ€เจ
[explanation.tensor.ru 'เจคเฉ‡ เจฆเฉ‡เจ–เฉ‹]

เจœเจฟเจตเฉ‡เจ‚ เจ‰เจฎเฉ€เจฆ เจ•เฉ€เจคเฉ€ เจ—เจˆ เจธเฉ€, เจธเจพเจจเฉ‚เฉฐ เจธเจพเจฐเฉ‡ 30 เจฐเจฟเจ•เจพเจฐเจก เจฎเจฟเจฒเฉ‡ เจนเจจเฅค เจชเจฐ เจ‰เจนเจจเจพเจ‚ เจจเฉ‡ เจ‡เจธ 'เจคเฉ‡ เจ•เฉเฉฑเจฒ เจธเจฎเฉ‡เจ‚ เจฆเจพ 60% เจ–เจฐเจš เจ•เฉ€เจคเจพ - เจ•เจฟเจ‰เจ‚เจ•เจฟ เจ‰เจนเจจเจพเจ‚ เจจเฉ‡ เจธเฉ‚เจšเจ•เจพเจ‚เจ• เจตเจฟเฉฑเจš 30 เจ–เฉ‹เจœเจพเจ‚ เจตเฉ€ เจ•เฉ€เจคเฉ€เจ†เจ‚ เจธเจจ. เจ•เฉ€ เจ˜เฉฑเจŸ เจ•เจฐเจจเจพ เจธเฉฐเจญเจต เจนเฉˆ?

เจธเฉ‚เจšเจ•เจพเจ‚เจ• เจฆเฉเจ†เจฐเจพ เจฌเจฒเจ• เจชเจฐเฉ‚เจซ เจฐเฉ€เจกเจฟเฉฐเจ—

เจ•เฉ€ เจธเจพเจจเฉ‚เฉฐ เจนเจฐเฉ‡เจ• เจจเฉ‹เจก เจฒเจˆ เจ‡เฉฑเจ• เจตเฉฑเจ–เจฐเฉ€ เจ‡เฉฐเจกเฉˆเจ•เจธ เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจ•เจฐเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ? เจ‡เจน เจชเจคเจพ เจšเจฒเจฆเจพ เจนเฉˆ เจ•เจฟ เจจเจนเฉ€เจ‚ - เจ…เจธเฉ€เจ‚ เจธเฉ‚เจšเจ•เจพเจ‚เจ• เจคเฉ‹เจ‚ เจชเฉœเฉเจน เจธเจ•เจฆเฉ‡ เจนเจพเจ‚ เจ‡เฉฑเจ• เจ•เจพเจฒ เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจตเจพเจฐ เจตเจฟเฉฑเจš เจ•เจˆ เจ•เฉเฉฐเจœเฉ€เจ†เจ‚ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจเจพ เจฆเฉ€ เจธเจนเจพเจ‡เจคเจพ เจจเจพเจฒ = ANY(array).

เจ…เจคเฉ‡ เจชเจ›เจพเจฃเจ•เจฐเจคเจพเจตเจพเจ‚ เจฆเฉ‡ เจ…เจœเจฟเจนเฉ‡ เจนเจฐเฉ‡เจ• เจธเจฎเฉ‚เจน เจตเจฟเฉฑเจš เจ…เจธเฉ€เจ‚ "เจจเฉ‹เจกเจธ" เจฆเฉเจ†เจฐเจพ เจชเจฟเจ›เจฒเฉ‡ เจชเฉœเจพเจ… เจตเจฟเฉฑเจš เจฒเฉฑเจญเฉ€เจ†เจ‚ เจธเจพเจฐเฉ€เจ†เจ‚ IDs เจฒเฉˆ เจธเจ•เจฆเฉ‡ เจนเจพเจ‚เฅค เจญเจพเจต, เจนเจฐ เจ…เจ—เจฒเฉ‡ เจชเฉœเจพเจ… 'เจคเฉ‡ เจ…เจธเฉ€เจ‚ เจ•เจฐเจพเจ‚เจ—เฉ‡ เจ‡เฉฑเจ• เจตเจพเจฐ เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจ–เจพเจธ เจชเฉฑเจงเจฐ เจฆเฉ‡ เจธเจพเจฐเฉ‡ เจตเฉฐเจธเจผเจœเจพเจ‚ เจฆเฉ€ เจ–เฉ‹เจœ เจ•เจฐเฉ‹.

เจธเจฟเจฐเจซ, เจ‡เฉฑเจฅเฉ‡ เจธเจฎเฉฑเจธเจฟเจ† เจนเฉˆ, เจ†เจตเจฐเจคเฉ€ เจšเฉ‹เจฃ เจตเจฟเฉฑเจš, เจคเฉเจธเฉ€เจ‚ เจ‡เฉฑเจ• เจจเฉ‡เจธเจŸเจก เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจตเจฟเฉฑเจš เจ†เจชเจฃเฉ‡ เจ†เจช เจจเฉ‚เฉฐ เจเจ•เจธเฉˆเจธ เจจเจนเฉ€เจ‚ เจ•เจฐ เจธเจ•เจฆเฉ‡ เจนเฉ‹, เจชเจฐ เจธเจพเจจเฉ‚เฉฐ เจ•เจฟเจธเฉ‡ เจคเจฐเฉเจนเจพเจ‚ เจธเจฟเจฐเจซเจผ เจ‰เจนเฉ€ เจšเฉเจฃเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ เจœเฉ‹ เจชเจฟเจ›เจฒเฉ‡ เจชเฉฑเจงเจฐ 'เจคเฉ‡ เจชเจพเจ‡เจ† เจ—เจฟเจ† เจธเฉ€... เจ‡เจน เจชเจคเจพ เจšเจฒเจฆเจพ เจนเฉˆ เจ•เจฟ เจชเฉ‚เจฐเฉ€ เจšเฉ‹เจฃ เจฒเจˆ เจจเฉ‡เจธเจŸเจก เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจ•เจฐเจจเจพ เจ…เจธเฉฐเจญเจต เจนเฉˆ, เจชเจฐ เจ‡เจธเจฆเฉ‡ เจ–เจพเจธ เจ–เฉ‡เจคเจฐ เจฒเจˆ เจ‡เจน เจธเฉฐเจญเจต เจนเฉˆเฅค เจ…เจคเฉ‡ เจ‡เจน เจ–เฉ‡เจคเจฐ เจ‡เฉฑเจ• เจเจฐเฉ‡ เจตเฉ€ เจนเฉ‹ เจธเจ•เจฆเจพ เจนเฉˆ - เจœเฉ‹ เจ•เจฟ เจธเจพเจจเฉ‚เฉฐ เจตเจฐเจคเจฃ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ ANY.

เจ‡เจน เจฅเฉ‹เฉœเจพ เจชเจพเจ—เจฒ เจฒเฉฑเจ—เจฆเจพ เจนเฉˆ, เจชเจฐ เจšเจฟเฉฑเจคเจฐ เจตเจฟเฉฑเจš เจธเจญ เจ•เฉเจ เจธเจงเจพเจฐเจจ เจนเฉˆ.

PostgreSQL เจเจ‚เจŸเฉ€เจชเฉˆเจŸเจฐเจจ: เจ–เจฐเจ—เฉ‹เจธเจผ เจฆเจพ เจฎเฉ‹เจฐเฉ€ เจ•เจฟเฉฐเจจเจพ เจกเฉ‚เฉฐเจ˜เจพ เจนเฉˆ? เจ†เจ“ เจฒเฉœเฉ€เจตเจพเจฐ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจฒเฉฐเจ˜เฉ€เจ

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;

PostgreSQL เจเจ‚เจŸเฉ€เจชเฉˆเจŸเจฐเจจ: เจ–เจฐเจ—เฉ‹เจธเจผ เจฆเจพ เจฎเฉ‹เจฐเฉ€ เจ•เจฟเฉฐเจจเจพ เจกเฉ‚เฉฐเจ˜เจพ เจนเฉˆ? เจ†เจ“ เจฒเฉœเฉ€เจตเจพเจฐ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจฒเฉฐเจ˜เฉ€เจ
[explanation.tensor.ru 'เจคเฉ‡ เจฆเฉ‡เจ–เฉ‹]

เจ…เจคเฉ‡ เจ‡เฉฑเจฅเฉ‡ เจธเจญ เจคเฉ‹เจ‚ เจฎเจนเฉฑเจคเจตเจชเฉ‚เจฐเจฃ เจ—เฉฑเจฒ เจ‡เจน เจตเฉ€ เจจเจนเฉ€เจ‚ เจนเฉˆ เจธเจฎเฉ‡เจ‚ เจตเจฟเฉฑเจš 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, เจœเฉ‹ เจธเจพเจจเฉ‚เฉฐ เจฐเฉ€เจ•เจฐเจธเจฟเจต "เจŸเฉ‡เจฌเจฒ" เจฆเฉ‡ เจ–เฉ‡เจคเจฐเจพเจ‚ เจจเฉ‚เฉฐ เจคเฉเจฐเฉฐเจค เจเจ•เจธเฉˆเจธ เจ•เจฐเจจ เจฆเฉ€ เจ‡เจœเจพเจœเจผเจค เจฆเฉ‡เจตเฉ‡เจ—เจพ, เจ…เจคเฉ‡ เจ•เฉเฉฐเจœเฉ€เจ†เจ‚ เจฆเฉ‡ เจธเฉˆเฉฑเจŸ เจจเฉ‚เฉฐ เจ˜เจŸเจพเจ‰เจฃ เจฒเจˆ เจ‡เฉฑเจ• เจจเฉ‹เจก 'เจคเฉ‡ เจ†เจงเจพเจฐเจฟเจค เจซเจฟเจฒเจŸเจฐเจฟเฉฐเจ— เจธเจฅเจฟเจคเฉ€ เจฆเฉ‡ เจจเจพเจฒ เจ‡เฉฑเจ• เจ•เฉเฉฑเจฒ เจซเฉฐเจ•เจธเจผเจจ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเฉ‹:

PostgreSQL เจเจ‚เจŸเฉ€เจชเฉˆเจŸเจฐเจจ: เจ–เจฐเจ—เฉ‹เจธเจผ เจฆเจพ เจฎเฉ‹เจฐเฉ€ เจ•เจฟเฉฐเจจเจพ เจกเฉ‚เฉฐเจ˜เจพ เจนเฉˆ? เจ†เจ“ เจฒเฉœเฉ€เจตเจพเจฐ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจฒเฉฐเจ˜เฉ€เจ

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;

PostgreSQL เจเจ‚เจŸเฉ€เจชเฉˆเจŸเจฐเจจ: เจ–เจฐเจ—เฉ‹เจธเจผ เจฆเจพ เจฎเฉ‹เจฐเฉ€ เจ•เจฟเฉฐเจจเจพ เจกเฉ‚เฉฐเจ˜เจพ เจนเฉˆ? เจ†เจ“ เจฒเฉœเฉ€เจตเจพเจฐ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจฒเฉฐเจ˜เฉ€เจ
[explanation.tensor.ru 'เจคเฉ‡ เจฆเฉ‡เจ–เฉ‹]

เจ…เจธเฉ€เจ‚ เจ‡เฉฑเจ• เจนเฉ‹เจฐ เจ‡เฉฐเจกเฉˆเจ•เจธ เจ•เจพเจฒ เจจเฉ‚เฉฐ เจ˜เจŸเจพเจ‰เจฃ เจฆเฉ‡ เจฏเฉ‹เจ— เจธเฉ€ เจ…เจคเฉ‡ เจตเจพเจฒเฉ€เจ…เจฎ เจตเจฟเฉฑเจš 2 เจคเฉ‹เจ‚ เจตเฉฑเจง เจตเจพเจฐ เจœเจฟเฉฑเจคเจฟเจ† เจชเจฐเฉ‚เจซ เจฐเฉ€เจก

#2. เจ†เจ“ เจœเฉœเฉเจนเจพเจ‚ เจตเฉฑเจฒ เจตเจพเจชเจธ เจšเฉฑเจฒเฉ€เจ

เจ‡เจน เจเจฒเจ—เฉ‹เจฐเจฟเจฆเจฎ เจฒเจพเจญเจฆเจพเจ‡เจ• เจนเฉ‹เจตเฉ‡เจ—เจพ เจœเฉ‡เจ•เจฐ เจคเฉเจนเจพเจจเฉ‚เฉฐ "เจฐเฉเฉฑเจ– เจฆเฉ‡ เจ‰เฉฑเจชเจฐ" เจธเจพเจฐเฉ‡ เจคเฉฑเจคเจพเจ‚ เจฒเจˆ เจฐเจฟเจ•เจพเจฐเจก เจ‡เจ•เฉฑเจ เฉ‡ เจ•เจฐเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉˆ, เจ‡เจธ เจฌเจพเจฐเฉ‡ เจœเจพเจฃเจ•เจพเจฐเฉ€ เจจเฉ‚เฉฐ เจฌเจฐเจ•เจฐเจพเจฐ เจฐเฉฑเจ–เจฆเฉ‡ เจนเฉ‹เจ เจ•เจฟ เจ•เจฟเจนเฉœเฉ€ เจธเจฐเฉ‹เจค เจธเจผเฉ€เจŸ (เจ…เจคเฉ‡ เจ•เจฟเจนเฉœเฉ‡ เจธเฉฐเจ•เฉ‡เจคเจพเจ‚ เจจเจพเจฒ) เจ‡เจธ เจจเฉ‚เฉฐ เจจเจฎเฉ‚เจจเฉ‡ เจตเจฟเฉฑเจš เจธเจผเจพเจฎเจฒ เจ•เจฐเจจ เจฆเจพ เจ•เจพเจฐเจจ เจฌเจฃเฉ€ - เจ‰เจฆเจพเจนเจฐเจจ เจฒเจˆ, เจ‡เฉฑเจ• เจธเฉฐเจ–เฉ‡เจช เจฐเจฟเจชเฉ‹เจฐเจŸ เจฌเจฃเจพเจ‰เจฃ เจฒเจˆ เจจเฉ‹เจกเจพเจ‚ เจตเจฟเฉฑเจš เจเจ•เฉ€เจ•เจฐเจฃ เจฆเฉ‡ เจจเจพเจฒ.

PostgreSQL เจเจ‚เจŸเฉ€เจชเฉˆเจŸเจฐเจจ: เจ–เจฐเจ—เฉ‹เจธเจผ เจฆเจพ เจฎเฉ‹เจฐเฉ€ เจ•เจฟเฉฐเจจเจพ เจกเฉ‚เฉฐเจ˜เจพ เจนเฉˆ? เจ†เจ“ เจฒเฉœเฉ€เจตเจพเจฐ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจฒเฉฐเจ˜เฉ€เจ
เจนเฉ‡เจ  เจฒเจฟเจ–เฉ€เจ†เจ‚ เจ—เฉฑเจฒเจพเจ‚ เจจเฉ‚เฉฐ เจธเจฟเจฐเจซเจผ เจธเฉฐเจ•เจฒเจช เจฆเฉ‡ เจธเจฌเฉ‚เจค เจตเจœเฉ‹เจ‚ เจฒเจฟเจ† เจœเจพเจฃเจพ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆ, เจ•เจฟเจ‰เจ‚เจ•เจฟ เจฌเฉ‡เจจเจคเฉ€ เจฌเจนเฉเจค เจฌเฉ‹เจเจฒ เจธเจพเจฌเจค เจนเฉเฉฐเจฆเฉ€ เจนเฉˆเฅค เจชเจฐ เจœเฉ‡ เจ‡เจน เจคเฉเจนเจพเจกเฉ‡ เจกเฉ‡เจŸเจพเจฌเฉ‡เจธ 'เจคเฉ‡ เจนเจพเจตเฉ€ เจนเฉˆ, เจคเจพเจ‚ เจคเฉเจนเจพเจจเฉ‚เฉฐ เจธเจฎเจพเจจ เจคเจ•เจจเฉ€เจ•เจพเจ‚ เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจจ เจฌเจพเจฐเฉ‡ เจธเฉ‹เจšเจฃเจพ เจšเจพเจนเฉ€เจฆเจพ เจนเฉˆ.

เจ†เจ‰ เจ•เฉเจ เจธเจงเจพเจฐเจจ เจ•เจฅเจจเจพเจ‚ เจจเจพเจฒ เจธเจผเฉเจฐเฉ‚ เจ•เจฐเฉ€เจ:

  • เจกเฉ‡เจŸเจพเจฌเฉ‡เจธ เจคเฉ‹เจ‚ เจ‰เจนเฉ€ เจฐเจฟเจ•เจพเจฐเจก เจ‡เจธ เจจเฉ‚เฉฐ เจธเจฟเจฐเจซเจผ เจ‡เฉฑเจ• เจตเจพเจฐ เจชเฉœเฉเจนเจจเจพ เจธเจญ เจคเฉ‹เจ‚ เจตเจงเฉ€เจ† เจนเฉˆ.
  • เจกเจพเจŸเจพเจฌเฉ‡เจธ เจคเฉ‹เจ‚ เจฐเจฟเจ•เจพเจฐเจก เจฌเฉˆเจšเจพเจ‚ เจตเจฟเฉฑเจš เจชเฉœเฉเจนเจจเจพ เจตเจงเฉ‡เจฐเฉ‡ เจ•เฉเจธเจผเจฒ เจนเฉˆเจ‡เจ•เฉฑเจฒเฉ‡ เจจเจพเจฒเฉ‹เจ‚.

เจนเฉเจฃ เจธเจพเจจเฉ‚เฉฐ เจฒเฉ‹เฉœเฉ€เจ‚เจฆเฉ€ เจฌเฉ‡เจจเจคเฉ€ เจจเฉ‚เฉฐ เจฌเจฃเจพเจ‰เจฃ เจฆเฉ€ เจ•เฉ‹เจธเจผเจฟเจธเจผ เจ•เจฐเฉ€เจเฅค

เจ•เจฆเจฎ 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

เจนเฉเจฃ เจธเจพเจจเฉ‚เฉฐ เจธเฉˆเจ•เจธเจผเจจ เจ†เจˆเจกเฉ€ เจฆเจพ เจ‡เฉฑเจ• เจธเฉˆเฉฑเจŸ เจฎเจฟเจฒเฉ‡เจ—เจพ เจœเจฟเจธเจจเฉ‚เฉฐ เจ…เฉฑเจ—เฉ‡ เจชเฉœเฉเจนเจจ เจฆเฉ€ เจฒเฉ‹เฉœ เจนเฉ‹เจตเฉ‡เจ—เฉ€เฅค เจฒเจ—เจญเจ— เจนเจฎเฉ‡เจธเจผเจพ เจ‰เจน เจ…เจธเจฒเฉ€ เจธเฉˆเฉฑเจŸ เจฆเฉ‡ เจตเฉฑเจ–-เจตเฉฑเจ– เจฐเจฟเจ•เจพเจฐเจกเจพเจ‚ เจตเจฟเฉฑเจš เจกเฉเจชเจฒเฉ€เจ•เฉ‡เจŸ เจ•เฉ€เจคเฉ‡ เจœเจพเจฃเจ—เฉ‡ - เจ‡เจธ เจฒเจˆ เจ…เจธเฉ€เจ‚ เจ•เจฐเจพเจ‚เจ—เฉ‡ เจ‰เจนเจจเจพเจ‚ เจจเฉ‚เฉฐ เจธเจฎเฉ‚เจน, เจธเจฐเฉ‹เจค เจชเฉฑเจคเจฟเจ†เจ‚ เจฌเจพเจฐเฉ‡ เจœเจพเจฃเจ•เจพเจฐเฉ€ เจจเฉ‚เฉฐ เจธเฉเจฐเฉฑเจ–เจฟเจ…เจค เจ•เจฐเจฆเฉ‡ เจนเฉ‹เจเฅค

เจชเจฐ เจ‡เฉฑเจฅเฉ‡ เจคเจฟเฉฐเจจ เจฎเฉเจธเฉ€เจฌเจคเจพเจ‚ เจธเจพเจกเฉ€ เจ‰เจกเฉ€เจ• เจ•เจฐ เจฐเจนเฉ€เจ†เจ‚ เจนเจจ:

  1. เจชเฉเฉฑเจ›เจ—เจฟเฉฑเจ› เจฆเฉ‡ "เจธเจฌเจฐเฉ‡เจ•เจฐเจธเจฟเจต" เจนเจฟเฉฑเจธเฉ‡ เจตเจฟเฉฑเจš เจ‡เจธ เจจเจพเจฒ เจ•เฉเฉฑเจฒ เจซเฉฐเจ•เจธเจผเจจ เจธเจผเจพเจฎเจฒ เจจเจนเฉ€เจ‚ เจนเฉ‹ เจธเจ•เจฆเฉ‡ เจนเจจ GROUP BY.
  2. เจ‡เฉฑเจ• เจ†เจตเจฐเจคเฉ€ "เจธเจพเจฐเจฃเฉ€" เจฆเจพ เจนเจตเจพเจฒเจพ เจ‡เฉฑเจ• เจจเฉ‡เจธเจŸเจก เจธเจฌเจ•เจตเฉ‡เจฐเฉ€ เจตเจฟเฉฑเจš เจจเจนเฉ€เจ‚ เจนเฉ‹ เจธเจ•เจฆเจพ เจนเฉˆเฅค
  3. เจ†เจตเจฐเจคเฉ€ เจญเจพเจ— เจตเจฟเฉฑเจš เจ‡เฉฑเจ• เจฌเฉ‡เจจเจคเฉ€ เจตเจฟเฉฑเจš 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

เจซเจพเจˆเจจเจฒ เจฒเจˆ เจธเจพเจกเฉ‡ เจ•เฉ‹เจฒ เจ•เฉเจ เจจเจนเฉ€เจ‚ เจฌเจšเจฟเจ† เจนเฉˆ:

  • เจ…เจธเฉ€เจ‚ เจธเจฎเฉ‚เจน เจ†เจˆเจกเฉ€ เจฆเฉ‡ เจธเฉˆเฉฑเจŸ เจฆเฉ‡ เจ†เจงเจพเจฐ 'เจคเฉ‡ "เจธเฉˆเจ•เจธเจผเจจ" เจฐเจฟเจ•เจพเจฐเจก เจชเฉœเฉเจนเจฆเฉ‡ เจนเจพเจ‚
  • เจ…เจธเฉ€เจ‚ เจ˜เจŸเจพเจ เจ—เจ เจญเจพเจ—เจพเจ‚ เจฆเฉ€ เจฎเฉ‚เจฒ เจธเจผเฉ€เจŸเจพเจ‚ เจฆเฉ‡ "เจธเฉˆเจŸเจพเจ‚" เจจเจพเจฒ เจคเฉเจฒเจจเจพ เจ•เจฐเจฆเฉ‡ เจนเจพเจ‚
  • เจฆเฉ€ เจตเจฐเจคเฉ‹เจ‚ เจ•เจฐเจ•เฉ‡ เจธเฉˆเฉฑเจŸ-เจธเจŸเฉเจฐเจฟเฉฐเจ— เจฆเจพ "เจชเจธเจพเจฐ" เจ•เจฐเฉ‹ 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;

PostgreSQL เจเจ‚เจŸเฉ€เจชเฉˆเจŸเจฐเจจ: เจ–เจฐเจ—เฉ‹เจธเจผ เจฆเจพ เจฎเฉ‹เจฐเฉ€ เจ•เจฟเฉฐเจจเจพ เจกเฉ‚เฉฐเจ˜เจพ เจนเฉˆ? เจ†เจ“ เจฒเฉœเฉ€เจตเจพเจฐ เจตเจฟเฉฑเจšเฉ‹เจ‚ เจฒเฉฐเจ˜เฉ€เจ
[explanation.tensor.ru 'เจคเฉ‡ เจฆเฉ‡เจ–เฉ‹]

เจธเจฐเฉ‹เจค: www.habr.com

เจ‡เฉฑเจ• เจŸเจฟเฉฑเจชเจฃเฉ€ เจœเฉ‹เฉœเฉ‹