PostgreSQL āĻ…ā§āĻ¯āĻžāĻ¨ā§āĻŸāĻŋāĻĒā§āĻ¯āĻžāĻŸāĻžāĻ°ā§āĻ¨āĻ¸: āĻ–āĻ°āĻ—ā§‹āĻļā§‡āĻ° āĻ—āĻ°ā§āĻ¤ āĻ•āĻ¤āĻŸāĻž āĻ—āĻ­ā§€āĻ°? āĻāĻ° āĻļā§āĻ°ā§‡āĻŖā§€āĻŦāĻŋāĻ¨ā§āĻ¯āĻžāĻ¸ āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§‡ āĻ¯āĻžāĻ¨

āĻœāĻŸāĻŋāĻ˛ āĻ‡āĻ†āĻ°āĻĒāĻŋ āĻ¸āĻŋāĻ¸ā§āĻŸā§‡āĻŽā§‡ āĻ…āĻ¨ā§‡āĻ• āĻ¸āĻ¤ā§āĻ¤ā§āĻŦāĻž āĻāĻ•āĻŸāĻŋ āĻļā§āĻ°ā§‡āĻŖāĻŋāĻŦāĻĻā§āĻ§ āĻĒā§āĻ°āĻ•ā§ƒāĻ¤āĻŋ āĻ†āĻ›ā§‡āĻ¯āĻ–āĻ¨ āĻ¸āĻŽāĻœāĻžāĻ¤ā§€āĻ¯āĻŧ āĻŦāĻ¸ā§āĻ¤ā§āĻ—ā§āĻ˛āĻŋ āĻ¸āĻžāĻ°āĻŋāĻŦāĻĻā§āĻ§ āĻšāĻ¯āĻŧ āĻĒā§‚āĻ°ā§āĻŦāĻĒā§āĻ°ā§āĻˇ-āĻŦāĻ‚āĻļā§€āĻ¯āĻŧ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡āĻ° āĻ—āĻžāĻ› - āĻāĻŸāĻŋ āĻāĻ¨ā§āĻŸāĻžāĻ°āĻĒā§āĻ°āĻžāĻ‡āĻœā§‡āĻ° āĻ¸āĻžāĻ‚āĻ—āĻ āĻ¨āĻŋāĻ• āĻ•āĻžāĻ āĻžāĻŽā§‹ (āĻāĻ‡ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻļāĻžāĻ–āĻž, āĻŦāĻŋāĻ­āĻžāĻ— āĻāĻŦāĻ‚ āĻ•āĻžāĻœā§‡āĻ° āĻ—ā§āĻ°ā§āĻĒ), āĻāĻŦāĻ‚ āĻĒāĻŖā§āĻ¯ā§‡āĻ° āĻ•ā§āĻ¯āĻžāĻŸāĻžāĻ˛āĻ—, āĻāĻŦāĻ‚ āĻ•āĻžāĻœā§‡āĻ° āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ° āĻāĻŦāĻ‚ āĻŦāĻŋāĻ•ā§āĻ°āĻ¯āĻŧ āĻĒāĻ¯āĻŧā§‡āĻ¨ā§āĻŸāĻ—ā§āĻ˛āĻŋāĻ° āĻ­ā§‚āĻ—ā§‹āĻ˛, ...

PostgreSQL āĻ…ā§āĻ¯āĻžāĻ¨ā§āĻŸāĻŋāĻĒā§āĻ¯āĻžāĻŸāĻžāĻ°ā§āĻ¨āĻ¸: āĻ–āĻ°āĻ—ā§‹āĻļā§‡āĻ° āĻ—āĻ°ā§āĻ¤ āĻ•āĻ¤āĻŸāĻž āĻ—āĻ­ā§€āĻ°? āĻāĻ° āĻļā§āĻ°ā§‡āĻŖā§€āĻŦāĻŋāĻ¨ā§āĻ¯āĻžāĻ¸ āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§‡ āĻ¯āĻžāĻ¨

āĻ†āĻ¸āĻ˛ā§‡, āĻ¸ā§‡āĻ–āĻžāĻ¨ā§‡ āĻ•ā§‡āĻ‰ āĻ¨ā§‡āĻ‡ āĻŦā§āĻ¯āĻŦāĻ¸āĻž āĻ…āĻŸā§‹āĻŽā§‡āĻļāĻ¨ āĻāĻ˛āĻžāĻ•āĻž, āĻ¯ā§‡āĻ–āĻžāĻ¨ā§‡ āĻĢāĻ˛āĻ¸ā§āĻŦāĻ°ā§‚āĻĒ āĻ•ā§‹āĻ¨ā§‹ āĻļā§āĻ°ā§‡āĻŖāĻŋāĻŦāĻŋāĻ¨ā§āĻ¯āĻžāĻ¸ āĻĨāĻžāĻ•āĻŦā§‡ āĻ¨āĻžāĨ¤ āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻ†āĻĒāĻ¨āĻŋ "āĻŦā§āĻ¯āĻŦāĻ¸āĻžāĻ° āĻœāĻ¨ā§āĻ¯" āĻ•āĻžāĻœ āĻ¨āĻž āĻ•āĻ°āĻ˛ā§‡āĻ“, āĻ†āĻĒāĻ¨āĻŋ āĻāĻ–āĻ¨āĻ“ āĻ¸āĻšāĻœā§‡āĻ‡ āĻļā§āĻ°ā§‡āĻŖā§€āĻŦāĻĻā§āĻ§ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•āĻ—ā§āĻ˛āĻŋāĻ° āĻ¸āĻŽā§āĻŽā§āĻ–ā§€āĻ¨ āĻšāĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĻ¨āĨ¤ āĻāĻŸāĻž āĻŸā§āĻ°āĻžāĻ‡āĻŸ, āĻāĻŽāĻ¨āĻ•āĻŋ āĻ†āĻĒāĻ¨āĻžāĻ° āĻĢā§āĻ¯āĻžāĻŽāĻŋāĻ˛āĻŋ āĻŸā§āĻ°āĻŋ āĻŦāĻž āĻļāĻĒāĻŋāĻ‚ āĻ¸ā§‡āĻ¨ā§āĻŸāĻžāĻ°ā§‡ āĻĒā§āĻ°āĻžāĻ™ā§āĻ—āĻ¨ā§‡āĻ° āĻŽā§‡āĻā§‡ āĻĒāĻ°āĻŋāĻ•āĻ˛ā§āĻĒāĻ¨āĻž āĻāĻ•āĻ‡ āĻ•āĻžāĻ āĻžāĻŽā§‹āĨ¤

āĻĄāĻŋāĻŦāĻŋāĻāĻŽāĻāĻ¸ā§‡ āĻāĻ‡ āĻœāĻžāĻ¤ā§€āĻ¯āĻŧ āĻ—āĻžāĻ› āĻ¸āĻ‚āĻ°āĻ•ā§āĻˇāĻŖ āĻ•āĻ°āĻžāĻ° āĻ…āĻ¨ā§‡āĻ• āĻ‰āĻĒāĻžāĻ¯āĻŧ āĻ°āĻ¯āĻŧā§‡āĻ›ā§‡, āĻ¤āĻŦā§‡ āĻ†āĻœ āĻ†āĻŽāĻ°āĻž āĻ•ā§‡āĻŦāĻ˛ āĻāĻ•āĻŸāĻŋ āĻŦāĻŋāĻ•āĻ˛ā§āĻĒā§‡āĻ° āĻ‰āĻĒāĻ° āĻĢā§‹āĻ•āĻžāĻ¸ āĻ•āĻ°āĻŦ:

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

CREATE INDEX ON hier(pid); -- ĐŊĐĩ СайŅ‹Đ˛Đ°ĐĩĐŧ, Ņ‡Ņ‚Đž FK ĐŊĐĩ ĐŋОдŅ€Đ°ĐˇŅƒĐŧĐĩваĐĩŅ‚ авŅ‚ĐžŅĐžĐˇĐ´Đ°ĐŊиĐĩ иĐŊĐ´ĐĩĐēŅĐ°, в ĐžŅ‚ĐģиŅ‡Đ¸Đĩ ĐžŅ‚ PK

āĻāĻŦāĻ‚ āĻ†āĻĒāĻ¨āĻŋ āĻ¯āĻ–āĻ¨ āĻļā§āĻ°ā§‡āĻŖāĻŋāĻŦāĻŋāĻ¨ā§āĻ¯āĻžāĻ¸ā§‡āĻ° āĻ—āĻ­ā§€āĻ°āĻ¤āĻžāĻ° āĻŽāĻ§ā§āĻ¯ā§‡ āĻ‰āĻāĻ•āĻŋ āĻĻāĻŋāĻšā§āĻ›ā§‡āĻ¨, āĻ¤āĻ–āĻ¨ āĻ§ā§ˆāĻ°ā§āĻ¯ āĻ¸āĻšāĻ•āĻžāĻ°ā§‡ āĻāĻ‡ āĻ§āĻ°āĻ¨ā§‡āĻ° āĻ•āĻžāĻ āĻžāĻŽā§‹āĻ° āĻ¸āĻžāĻĨā§‡ āĻ•āĻžāĻœ āĻ•āĻ°āĻžāĻ° āĻ†āĻĒāĻ¨āĻžāĻ° "āĻ¨āĻŋāĻˇā§āĻĒāĻžāĻĒ" āĻ‰āĻĒāĻžāĻ¯āĻŧāĻ—ā§āĻ˛āĻŋ āĻ•āĻ¤āĻŸāĻž āĻ•āĻžāĻ°ā§āĻ¯āĻ•āĻ° āĻšāĻŦā§‡ āĻ¤āĻž āĻĻā§‡āĻ–āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ…āĻĒā§‡āĻ•ā§āĻˇāĻž āĻ•āĻ°āĻ›ā§‡āĨ¤

PostgreSQL āĻ…ā§āĻ¯āĻžāĻ¨ā§āĻŸāĻŋāĻĒā§āĻ¯āĻžāĻŸāĻžāĻ°ā§āĻ¨āĻ¸: āĻ–āĻ°āĻ—ā§‹āĻļā§‡āĻ° āĻ—āĻ°ā§āĻ¤ āĻ•āĻ¤āĻŸāĻž āĻ—āĻ­ā§€āĻ°? āĻāĻ° āĻļā§āĻ°ā§‡āĻŖā§€āĻŦāĻŋāĻ¨ā§āĻ¯āĻžāĻ¸ āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§‡ āĻ¯āĻžāĻ¨
āĻ†āĻ¸ā§āĻ¨ āĻ¸āĻžāĻ§āĻžāĻ°āĻŖ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻĻā§‡āĻ–āĻž āĻ¯āĻžāĻ•, āĻāĻ¸āĻ•āĻŋāĻ‰āĻāĻ˛-āĻ āĻ¤āĻžāĻĻā§‡āĻ° āĻŦāĻžāĻ¸ā§āĻ¤āĻŦāĻžāĻ¯āĻŧāĻ¨, āĻāĻŦāĻ‚ āĻ¤āĻžāĻĻā§‡āĻ° āĻ•āĻ°ā§āĻŽāĻ•ā§āĻˇāĻŽāĻ¤āĻž āĻ‰āĻ¨ā§āĻ¨āĻ¤ āĻ•āĻ°āĻžāĻ° āĻšā§‡āĻˇā§āĻŸāĻž āĻ•āĻ°ā§āĻ¨āĨ¤

#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;

āĻšāĻ˛ā§āĻ¨ āĻļā§āĻ°ā§ āĻ•āĻ°āĻž āĻ¯āĻžāĻ• āĻ¸āĻŦāĻšā§‡āĻ¯āĻŧā§‡ āĻ¸āĻšāĻœ āĻ•āĻžāĻœāĻŸāĻŋ - āĻāĻ•āĻŸāĻŋ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻ¸ā§‡āĻ•ā§āĻŸāĻ°ā§‡āĻ° āĻŽāĻ§ā§āĻ¯ā§‡ āĻ•āĻžāĻœ āĻ•āĻ°ā§‡ āĻāĻŽāĻ¨ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ•āĻ°ā§āĻŽāĻšāĻžāĻ°ā§€āĻĻā§‡āĻ° āĻ–ā§āĻāĻœā§‡ āĻŦā§‡āĻ° āĻ•āĻ°āĻž, āĻŦāĻž āĻ…āĻ¨ā§āĻ•ā§āĻ°āĻŽā§‡āĻ° āĻĒāĻ°āĻŋāĻĒā§āĻ°ā§‡āĻ•ā§āĻˇāĻŋāĻ¤ā§‡ - āĻāĻ•āĻŸāĻŋ āĻ¨ā§‹āĻĄā§‡āĻ° āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻļāĻŋāĻļā§ āĻ–ā§āĻāĻœā§āĻ¨. āĻāĻŸāĻŋ āĻŦāĻ‚āĻļāĻ§āĻ°ā§‡āĻ° "āĻ—āĻ­ā§€āĻ°āĻ¤āĻž" āĻĒā§‡āĻ¤ā§‡āĻ“ āĻ­āĻžāĻ˛ āĻšāĻŦā§‡... āĻāĻ‡ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ•āĻŋāĻ›ā§ āĻĒā§āĻ°āĻ¯āĻŧā§‹āĻœāĻ¨ āĻšāĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡, āĻ‰āĻĻāĻžāĻšāĻ°āĻŖāĻ¸ā§āĻŦāĻ°ā§‚āĻĒ, āĻ•āĻŋāĻ›ā§ āĻ§āĻ°āĻŖā§‡āĻ° āĻ¨āĻŋāĻ°ā§āĻŽāĻžāĻŖā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ‡ āĻ•āĻ°ā§āĻŽāĻšāĻžāĻ°ā§€āĻĻā§‡āĻ° āĻ†āĻ‡āĻĄāĻŋ āĻ¤āĻžāĻ˛āĻŋāĻ•āĻžāĻ° āĻ‰āĻĒāĻ° āĻ­āĻŋāĻ¤ā§āĻ¤āĻŋ āĻ•āĻ°ā§‡ āĻœāĻŸāĻŋāĻ˛ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻ¨.

āĻ¯āĻĻāĻŋ āĻāĻ‡ āĻŦāĻ‚āĻļāĻ§āĻ°āĻĻā§‡āĻ° āĻŽāĻžāĻ¤ā§āĻ° āĻ•āĻ¯āĻŧā§‡āĻ•āĻŸāĻŋ āĻ¸ā§āĻ¤āĻ° āĻĨāĻžāĻ•ā§‡ āĻāĻŦāĻ‚ āĻ¸āĻ‚āĻ–ā§āĻ¯āĻžāĻŸāĻŋ āĻāĻ• āĻĄāĻœāĻ¨ā§‡āĻ° āĻŽāĻ§ā§āĻ¯ā§‡ āĻĨāĻžāĻ•ā§‡ āĻ¤āĻŦā§‡ āĻ¸āĻŦāĻ•āĻŋāĻ›ā§ āĻ āĻŋāĻ• āĻšāĻŦā§‡, āĻ¤āĻŦā§‡ āĻ¯āĻĻāĻŋ 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 āĻ…ā§āĻ¯āĻžāĻ¨ā§āĻŸāĻŋāĻĒā§āĻ¯āĻžāĻŸāĻžāĻ°ā§āĻ¨āĻ¸: āĻ–āĻ°āĻ—ā§‹āĻļā§‡āĻ° āĻ—āĻ°ā§āĻ¤ āĻ•āĻ¤āĻŸāĻž āĻ—āĻ­ā§€āĻ°? āĻāĻ° āĻļā§āĻ°ā§‡āĻŖā§€āĻŦāĻŋāĻ¨ā§āĻ¯āĻžāĻ¸ āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§‡ āĻ¯āĻžāĻ¨
[explain.tensor.ru āĻĻā§‡āĻ–ā§āĻ¨]

āĻĒā§āĻ°āĻ¤ā§āĻ¯āĻžāĻļāĻŋāĻ¤ āĻšāĻŋāĻ¸āĻžāĻŦā§‡, āĻ†āĻŽāĻ°āĻž āĻ¸āĻŦ 30 āĻ°ā§‡āĻ•āĻ°ā§āĻĄ āĻ–ā§āĻāĻœā§‡ āĻĒā§‡āĻ¯āĻŧā§‡āĻ›āĻŋ. āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻ¤āĻžāĻ°āĻž āĻāĻ¤ā§‡ āĻŽā§‹āĻŸ āĻ¸āĻŽāĻ¯āĻŧā§‡āĻ° 60% āĻŦā§āĻ¯āĻ¯āĻŧ āĻ•āĻ°ā§‡āĻ›ā§‡ - āĻ•āĻžāĻ°āĻŖ āĻ¤āĻžāĻ°āĻž āĻ¸ā§‚āĻšāĻ•ā§‡ 30āĻŸāĻŋ āĻ…āĻ¨ā§āĻ¸āĻ¨ā§āĻ§āĻžāĻ¨āĻ“ āĻ•āĻ°ā§‡āĻ›ā§‡āĨ¤ āĻāĻŸāĻž āĻ•āĻŋ āĻ•āĻŽ āĻ•āĻ°āĻž āĻ¸āĻŽā§āĻ­āĻŦ?

āĻ¸ā§‚āĻšāĻ• āĻĻā§āĻŦāĻžāĻ°āĻž āĻŦāĻžāĻ˛ā§āĻ• āĻĒā§āĻ°ā§āĻĢāĻ°āĻŋāĻĄāĻŋāĻ‚

āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻ•āĻŋ āĻĒā§āĻ°āĻ¤āĻŋāĻŸāĻŋ āĻ¨ā§‹āĻĄā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻĒā§ƒāĻĨāĻ• āĻ¸ā§‚āĻšāĻ• āĻ•ā§āĻ¯ā§‹āĻ¯āĻŧāĻžāĻ°ā§€ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŦā§‡? āĻĻā§‡āĻ–āĻž āĻ¯āĻžāĻšā§āĻ›ā§‡ āĻ¯ā§‡ āĻ¨āĻž - āĻ†āĻŽāĻ°āĻž āĻ¸ā§‚āĻšāĻ• āĻĨā§‡āĻ•ā§‡ āĻĒāĻĄāĻŧāĻ¤ā§‡ āĻĒāĻžāĻ°āĻŋ āĻāĻ• āĻ•āĻ˛ā§‡ āĻāĻ•āĻŦāĻžāĻ°ā§‡ āĻāĻ•āĻžāĻ§āĻŋāĻ• āĻ•ā§€ āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻž āĻ¸āĻžāĻšāĻžāĻ¯ā§āĻ¯ā§‡ = ANY(array).

āĻāĻŦāĻ‚ āĻāĻ‡ āĻ§āĻ°āĻ¨ā§‡āĻ° āĻĒā§āĻ°āĻ¤āĻŋāĻŸāĻŋ āĻ†āĻ‡āĻĄā§‡āĻ¨ā§āĻŸāĻŋāĻĢāĻžāĻ¯āĻŧāĻžāĻ° āĻ—ā§āĻ°ā§āĻĒā§‡ āĻ†āĻŽāĻ°āĻž "āĻ¨ā§‹āĻĄ" āĻĻā§āĻŦāĻžāĻ°āĻž āĻĒā§‚āĻ°ā§āĻŦāĻŦāĻ°ā§āĻ¤ā§€ āĻ§āĻžāĻĒā§‡ āĻĒāĻžāĻ“āĻ¯āĻŧāĻž āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ†āĻ‡āĻĄāĻŋ āĻ¨āĻŋāĻ¤ā§‡ āĻĒāĻžāĻ°āĻŋāĨ¤ āĻ…āĻ°ā§āĻĨāĻžā§Ž, āĻĒā§āĻ°āĻ¤āĻŋāĻŸāĻŋ āĻĒāĻ°āĻŦāĻ°ā§āĻ¤ā§€ āĻ§āĻžāĻĒā§‡ āĻ†āĻŽāĻ°āĻž āĻ•āĻ°āĻŦ āĻāĻ•āĻŦāĻžāĻ°ā§‡ āĻāĻ•āĻŸāĻŋ āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻ¸ā§āĻ¤āĻ°ā§‡āĻ° āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻŦāĻ‚āĻļāĻ§āĻ°āĻĻā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ…āĻ¨ā§āĻ¸āĻ¨ā§āĻ§āĻžāĻ¨ āĻ•āĻ°ā§āĻ¨.

āĻļā§āĻ§ā§, āĻāĻ–āĻžāĻ¨ā§‡āĻ‡ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž, āĻĒā§āĻ¨āĻ°āĻžāĻŦā§ƒāĻ¤ā§āĻ¤ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻ¨ā§‡, āĻ†āĻĒāĻ¨āĻŋ āĻāĻ•āĻŸāĻŋ āĻ¨ā§‡āĻ¸ā§āĻŸā§‡āĻĄ āĻ•ā§āĻ¯ā§‹āĻ¯āĻŧāĻžāĻ°ā§€āĻ¤ā§‡ āĻ¨āĻŋāĻœā§‡āĻ•ā§‡ āĻ…ā§āĻ¯āĻžāĻ•ā§āĻ¸ā§‡āĻ¸ āĻ•āĻ°āĻ¤ā§‡ āĻĒāĻžāĻ°āĻŦā§‡āĻ¨ āĻ¨āĻž, āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻĒā§‚āĻ°ā§āĻŦāĻŦāĻ°ā§āĻ¤ā§€ āĻ¸ā§āĻ¤āĻ°ā§‡ āĻ¯āĻž āĻĒāĻžāĻ“āĻ¯āĻŧāĻž āĻ—ā§‡āĻ›ā§‡ āĻ¤āĻž āĻ†āĻŽāĻžāĻĻā§‡āĻ°āĻ•ā§‡ āĻ•ā§‹āĻ¨ā§‹āĻ­āĻžāĻŦā§‡ āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻ¨ āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŦā§‡... āĻĻā§‡āĻ–āĻž āĻ¯āĻžāĻšā§āĻ›ā§‡ āĻ¯ā§‡ āĻ¸āĻŽāĻ—ā§āĻ° āĻ¨āĻŋāĻ°ā§āĻŦāĻžāĻšāĻ¨ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻ¨ā§‡āĻ¸ā§āĻŸā§‡āĻĄ āĻ•ā§āĻ¯ā§‹āĻ¯āĻŧāĻžāĻ°ā§€ āĻ•āĻ°āĻž āĻ…āĻ¸āĻŽā§āĻ­āĻŦ, āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻāĻ° āĻ¨āĻŋāĻ°ā§āĻĻāĻŋāĻˇā§āĻŸ āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻŸāĻŋ āĻ¸āĻŽā§āĻ­āĻŦāĨ¤ āĻāĻŦāĻ‚ āĻāĻ‡ āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°āĻŸāĻŋ āĻāĻ•āĻŸāĻŋ āĻ…ā§āĻ¯āĻžāĻ°ā§‡āĻ“ āĻšāĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡ - āĻ¯āĻž āĻ†āĻŽāĻžāĻĻā§‡āĻ° āĻŦā§āĻ¯āĻŦāĻšāĻžāĻ° āĻ•āĻ°āĻ¤ā§‡ āĻšāĻŦā§‡ 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 āĻ…ā§āĻ¯āĻžāĻ¨ā§āĻŸāĻŋāĻĒā§āĻ¯āĻžāĻŸāĻžāĻ°ā§āĻ¨āĻ¸: āĻ–āĻ°āĻ—ā§‹āĻļā§‡āĻ° āĻ—āĻ°ā§āĻ¤ āĻ•āĻ¤āĻŸāĻž āĻ—āĻ­ā§€āĻ°? āĻāĻ° āĻļā§āĻ°ā§‡āĻŖā§€āĻŦāĻŋāĻ¨ā§āĻ¯āĻžāĻ¸ āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§‡ āĻ¯āĻžāĻ¨
[explain.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 āĻ…ā§āĻ¯āĻžāĻ¨ā§āĻŸāĻŋāĻĒā§āĻ¯āĻžāĻŸāĻžāĻ°ā§āĻ¨āĻ¸: āĻ–āĻ°āĻ—ā§‹āĻļā§‡āĻ° āĻ—āĻ°ā§āĻ¤ āĻ•āĻ¤āĻŸāĻž āĻ—āĻ­ā§€āĻ°? āĻāĻ° āĻļā§āĻ°ā§‡āĻŖā§€āĻŦāĻŋāĻ¨ā§āĻ¯āĻžāĻ¸ āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§‡ āĻ¯āĻžāĻ¨
[explain.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 āĻĨāĻžāĻ•āĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡ āĻ¨āĻžāĨ¤

āĻ¸ā§ŒāĻ­āĻžāĻ—ā§āĻ¯āĻŦāĻļāĻ¤, āĻāĻ‡ āĻ¸āĻŽāĻ¸ā§āĻ¤ āĻ¸āĻŽāĻ¸ā§āĻ¯āĻž āĻĒā§āĻ°āĻžāĻ¯āĻŧ āĻ•āĻžāĻœ āĻ•āĻ°āĻž āĻŦā§‡āĻļ āĻ¸āĻšāĻœāĨ¤ āĻļā§‡āĻˇ āĻĨā§‡āĻ•ā§‡ āĻļā§āĻ°ā§ āĻ•āĻ°āĻž āĻ¯āĻžāĻ•āĨ¤

āĻĒā§āĻ¨āĻ°āĻžāĻŦā§ƒāĻ¤ā§āĻ¤ āĻ…āĻ‚āĻļā§‡ CTE

āĻāĻ–āĻžāĻ¨ā§‡ āĻ¤āĻžāĻ‡ āĻ¨āĻž āĻ•āĻžāĻœ:

WITH RECURSIVE tree AS (
  ...
UNION ALL
  WITH T (...)
  SELECT ...
)

āĻāĻŦāĻ‚ āĻ¤āĻžāĻ‡ āĻāĻŸāĻŋ āĻ•āĻžāĻœ āĻ•āĻ°ā§‡, āĻŦāĻ¨ā§āĻ§āĻ¨ā§€ āĻĒāĻžāĻ°ā§āĻĨāĻ•ā§āĻ¯ āĻ¤ā§ˆāĻ°āĻŋ āĻ•āĻ°ā§‡!

WITH RECURSIVE tree AS (
  ...
UNION ALL
  (
    WITH T (...)
    SELECT ...
  )
)

āĻāĻ•āĻŸāĻŋ āĻĒā§āĻ¨āĻ°āĻžāĻŦā§ƒāĻ¤ā§āĻ¤ "āĻŸā§‡āĻŦāĻŋāĻ˛" āĻāĻ° āĻŦāĻŋāĻ°ā§āĻĻā§āĻ§ā§‡ āĻ¨ā§‡āĻ¸ā§āĻŸā§‡āĻĄ āĻ•ā§āĻ¯ā§‹āĻ¯āĻŧāĻžāĻ°ā§€

āĻšā§āĻŽ... āĻāĻ•āĻŸāĻŋ āĻĒā§āĻ¨āĻ°āĻžāĻŦā§ƒāĻ¤ā§āĻ¤ 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

āĻāĻ–āĻ¨ āĻ†āĻŽāĻ°āĻž āĻĻā§‡āĻ–āĻ¤ā§‡ āĻĒāĻžāĻšā§āĻ›āĻŋ āĻ•ā§‡āĻ¨ āĻ¸āĻžāĻ‚āĻ–ā§āĻ¯āĻŋāĻ• āĻ†āĻ‡āĻĄāĻŋāĻ•ā§‡ āĻŸā§‡āĻ•ā§āĻ¸āĻŸā§‡ āĻĒāĻ°āĻŋāĻŖāĻ¤ āĻ•āĻ°āĻž āĻšāĻ¯āĻŧā§‡āĻ›āĻŋāĻ˛ - āĻ¯āĻžāĻ¤ā§‡ āĻ¤āĻžāĻ°āĻž āĻ•āĻŽāĻž āĻĻāĻŋāĻ¯āĻŧā§‡ āĻ†āĻ˛āĻžāĻĻāĻž āĻ•āĻ°āĻž āĻ¯āĻžāĻ¯āĻŧ!

āĻĒāĻ‡āĻ āĻž 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 āĻ…ā§āĻ¯āĻžāĻ¨ā§āĻŸāĻŋāĻĒā§āĻ¯āĻžāĻŸāĻžāĻ°ā§āĻ¨āĻ¸: āĻ–āĻ°āĻ—ā§‹āĻļā§‡āĻ° āĻ—āĻ°ā§āĻ¤ āĻ•āĻ¤āĻŸāĻž āĻ—āĻ­ā§€āĻ°? āĻāĻ° āĻļā§āĻ°ā§‡āĻŖā§€āĻŦāĻŋāĻ¨ā§āĻ¯āĻžāĻ¸ āĻŽāĻžāĻ§ā§āĻ¯āĻŽā§‡ āĻ¯āĻžāĻ¨
[explain.tensor.ru āĻĻā§‡āĻ–ā§āĻ¨]

āĻ‰āĻ¤ā§āĻ¸: www.habr.com

āĻāĻ•āĻŸāĻŋ āĻŽāĻ¨ā§āĻ¤āĻŦā§āĻ¯ āĻœā§āĻĄāĻŧā§āĻ¨