Π‘Π£ΠΠ Π² ΡΡΠΎΠΌ ΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΠΈ ΡΠ°Π±ΠΎΡΠ°ΡΡ ΠΏΠΎ ΡΠ΅ΠΌ ΠΆΠ΅ ΠΏΡΠΈΠ½ΡΠΈΠΏΠ°ΠΌ β "ΡΠΊΠ°Π·Π°Π»ΠΈ ΠΊΠΎΠΏΠ°ΡΡ, Ρ ΠΈ ΠΊΠΎΠΏΠ°Ρ". ΠΠ°Ρ Π·Π°ΠΏΡΠΎΡ ΠΌΠΎΠΆΠ΅Ρ Π½Π΅ ΡΠΎΠ»ΡΠΊΠΎ Π·Π°ΡΠΎΡΠΌΠΎΠ·ΠΈΡΡ ΡΠΎΡΠ΅Π΄Π½ΠΈΠ΅ ΠΏΡΠΎΡΠ΅ΡΡΡ, ΠΏΠΎΡΡΠΎΡΠ½Π½ΠΎ Π·Π°Π½ΠΈΠΌΠ°Ρ ΡΠ΅ΡΡΡΡΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ°, Π½ΠΎ ΠΈ Β«ΡΡΠΎΠ½ΠΈΡΡΒ» Π²ΡΡ Π±Π°Π·Ρ ΡΠ΅Π»ΠΈΠΊΠΎΠΌ, Β«ΡΡΠ΅Π²Β» Π²ΡΡ Π΄ΠΎΡΡΡΠΏΠ½ΡΡ ΠΏΠ°ΠΌΡΡΡ. ΠΠΎΡΡΠΎΠΌΡ Π·Π°ΡΠΈΡΠ° ΠΎΡ Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΉ ΡΠ΅ΠΊΡΡΡΠΈΠΈ β ΠΎΠ±ΡΠ·Π°Π½Π½ΠΎΡΡΡ ΡΠ°ΠΌΠΎΠ³ΠΎ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°.
Π PostgreSQL Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ΅ΠΊΡΡΡΠΈΠ²Π½ΡΠ΅ Π·Π°ΠΏΡΠΎΡΡ ΡΠ΅ΡΠ΅Π· WITH RECURSIVE
ΠΠ΅ ΠΏΠΈΡΠ°ΡΡ ΡΠ΅ΠΊΡΡΡΠΈΠ²Π½ΡΠ΅ Π·Π°ΠΏΡΠΎΡΡ
Π ΠΏΠΈΡΠ°ΡΡ Π½Π΅ΡΠ΅ΠΊΡΡΡΠΈΠ²Π½ΡΠ΅. Π‘ ΡΠ²Π°ΠΆΠ΅Π½ΠΈΠ΅ΠΌ, ΠΠ°Ρ Π.Π.
ΠΠ° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅, PostgreSQL ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ Π±ΠΎΠ»ΡΡΠΎΠ΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»Π°, ΠΊΠΎΡΠΎΡΡΠΌ ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ, ΡΡΠΎΠ±Ρ Π½Π΅ ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡ ΡΠ΅ΠΊΡΡΡΠΈΡ.
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΏΡΠΈΠ½ΡΠΈΠΏΠΈΠ°Π»ΡΠ½ΠΎ Π΄ΡΡΠ³ΠΎΠΉ ΠΏΠΎΠ΄Ρ ΠΎΠ΄ ΠΊ Π·Π°Π΄Π°ΡΠ΅
ΠΠ½ΠΎΠ³Π΄Π° ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠΎΡΡΠΎ Π²Π·Π³Π»ΡΠ½ΡΡΡ Π½Π° Π·Π°Π΄Π°ΡΡ Β«Ρ Π΄ΡΡΠ³ΠΎΠΉ ΡΡΠΎΡΠΎΠ½ΡΒ». ΠΡΠΈΠΌΠ΅Ρ ΡΠ°ΠΊΠΎΠΉ ΡΠΈΡΡΠ°ΡΠΈΠΈ Ρ ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΠ» Π² ΡΡΠ°ΡΡΠ΅
WITH RECURSIVE src AS (
SELECT '{2,3,5,7,11,13,17,19}'::integer[] arr
)
, T(i, val) AS (
SELECT
1::bigint
, 1
UNION ALL
SELECT
i + 1
, val * arr[i]
FROM
T
, src
WHERE
i <= array_length(arr, 1)
)
SELECT
val
FROM
T
ORDER BY -- ΠΎΡΠ±ΠΎΡ ΡΠΈΠ½Π°Π»ΡΠ½ΠΎΠ³ΠΎ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ°
i DESC
LIMIT 1;
Π’Π°ΠΊΠΎΠΉ Π·Π°ΠΏΡΠΎΡ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡΡ Π½Π° Π²Π°ΡΠΈΠ°Π½Ρ ΠΎΡ Π·Π½Π°ΡΠΎΠΊΠΎΠ² ΠΌΠ°ΡΠ΅ΠΌΠ°ΡΠΈΠΊΠΈ:
WITH src AS (
SELECT unnest('{2,3,5,7,11,13,17,19}'::integer[]) prime
)
SELECT
exp(sum(ln(prime)))::integer val
FROM
src;
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ generate_series Π²ΠΌΠ΅ΡΡΠΎ ΡΠΈΠΊΠ»ΠΎΠ²
ΠΠΎΠΏΡΡΡΠΈΠΌ, ΠΏΠ΅ΡΠ΅Π΄ Π½Π°ΠΌΠΈ ΡΡΠΎΠΈΡ Π·Π°Π΄Π°ΡΠ° ΡΠ³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ Π²ΡΠ΅ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΠ΅ ΠΏΡΠ΅ΡΠΈΠΊΡΡ Π΄Π»Ρ ΡΡΡΠΎΠΊΠΈ 'abcdefgh'
:
WITH RECURSIVE T AS (
SELECT 'abcdefgh' str
UNION ALL
SELECT
substr(str, 1, length(str) - 1)
FROM
T
WHERE
length(str) > 1
)
TABLE T;
Π’ΠΎΡΠ½ΠΎ-ΡΠΎΡΠ½ΠΎ ΡΡΡ Π½ΡΠΆΠ½Π° ΡΠ΅ΠΊΡΡΡΠΈΡ?.. ΠΡΠ»ΠΈ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ LATERAL
ΠΈ generate_series
, ΡΠΎ Π΄Π°ΠΆΠ΅ CTE Π½Π΅ ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΡΡΡΡ:
SELECT
substr(str, 1, ln) str
FROM
(VALUES('abcdefgh')) T(str)
, LATERAL(
SELECT generate_series(length(str), 1, -1) ln
) X;
ΠΠ·ΠΌΠ΅Π½ΠΈΡΡ ΡΡΡΡΠΊΡΡΡΡ ΠΠ
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Ρ Π²Π°Ρ Π΅ΡΡΡ ΡΠ°Π±Π»ΠΈΡΠ° ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΡΠΎΡΡΠΌΠ° ΡΠΎ ΡΠ²ΡΠ·ΡΠΌΠΈ ΠΊΡΠΎ-ΠΊΠΎΠΌΡ ΠΎΡΠ²Π΅ΡΠΈΠ» ΠΈΠ»ΠΈ ΡΡΠ΅Π΄ Π²
CREATE TABLE message(
message_id
uuid
PRIMARY KEY
, reply_to
uuid
REFERENCES message
, body
text
);
CREATE INDEX ON message(reply_to);
ΠΡ ΠΈ ΡΠΈΠΏΠΎΠ²ΠΎΠΉ Π·Π°ΠΏΡΠΎΡ Π·Π°Π³ΡΡΠ·ΠΊΠΈ Π²ΡΠ΅Ρ
ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΠΉ ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΉ ΡΠ΅ΠΌΠ΅ Π²ΡΠ³Π»ΡΠ΄ΠΈΡ ΠΏΡΠΈΠΌΠ΅ΡΠ½ΠΎ ΡΠ°ΠΊ:
WITH RECURSIVE T AS (
SELECT
*
FROM
message
WHERE
message_id = $1
UNION ALL
SELECT
m.*
FROM
T
JOIN
message m
ON m.reply_to = T.message_id
)
TABLE T;
ΠΠΎ ΡΠ°Π· Ρ Π½Π°Ρ Π²ΡΠ΅Π³Π΄Π° Π½ΡΠΆΠ½Π° Π²ΡΡ ΡΠ΅ΠΌΠ° ΠΎΡ ΠΊΠΎΡΠ½Π΅Π²ΠΎΠ³ΠΎ ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ, ΡΠΎ ΠΏΠΎΡΠ΅ΠΌΡ Π±Ρ Π½Π°ΠΌ Π½Π΅ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ Π΅Π³ΠΎ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ Π² ΠΊΠ°ΠΆΠ΄ΡΡ Π·Π°ΠΏΠΈΡΡ Π°Π²ΡΠΎΠΌΠ°ΡΠΎΠΌ?
-- Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΏΠΎΠ»Π΅ Ρ ΠΎΠ±ΡΠΈΠΌ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΠΎΠΌ ΡΠ΅ΠΌΡ ΠΈ ΠΈΠ½Π΄Π΅ΠΊΡ Π½Π° Π½Π΅Π³ΠΎ
ALTER TABLE message
ADD COLUMN theme_id uuid;
CREATE INDEX ON message(theme_id);
-- ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·ΠΈΡΡΠ΅ΠΌ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡ ΡΠ΅ΠΌΡ Π² ΡΡΠΈΠ³Π³Π΅ΡΠ΅ ΠΏΡΠΈ Π²ΡΡΠ°Π²ΠΊΠ΅
CREATE OR REPLACE FUNCTION ins() RETURNS TRIGGER AS $$
BEGIN
NEW.theme_id = CASE
WHEN NEW.reply_to IS NULL THEN NEW.message_id -- Π±Π΅ΡΠ΅ΠΌ ΠΈΠ· ΡΡΠ°ΡΡΠΎΠ²ΠΎΠ³ΠΎ ΡΠΎΠ±ΡΡΠΈΡ
ELSE ( -- ΠΈΠ»ΠΈ ΠΈΠ· ΡΠΎΠΎΠ±ΡΠ΅Π½ΠΈΡ, Π½Π° ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΎΡΠ²Π΅ΡΠ°Π΅ΠΌ
SELECT
theme_id
FROM
message
WHERE
message_id = NEW.reply_to
)
END;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER ins BEFORE INSERT
ON message
FOR EACH ROW
EXECUTE PROCEDURE ins();
Π’Π΅ΠΏΠ΅ΡΡ Π²Π΅ΡΡ Π½Π°Ρ ΡΠ΅ΠΊΡΡΡΠΈΠ²Π½ΡΠΉ Π·Π°ΠΏΡΠΎΡ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΠ²Π΅Π΄Π΅Π½ Π²ΡΠ΅Π³ΠΎ Π»ΠΈΡΡ ΠΊ Π²ΠΎΡ ΡΠ°ΠΊΠΎΠΌΡ:
SELECT
*
FROM
message
WHERE
theme_id = $1;
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΏΡΠΈΠΊΠ»Π°Π΄Π½ΡΠ΅ Β«ΠΎΠ³ΡΠ°Π½ΠΈΡΠΈΡΠ΅Π»ΠΈΒ»
ΠΡΠ»ΠΈ ΠΏΠΎΠΌΠ΅Π½ΡΡΡ ΡΡΡΡΠΊΡΡΡΡ Π±Π°Π·Ρ ΠΌΡ Π½Π΅ Π² ΡΠΈΠ»Π°Ρ ΠΏΠΎ ΠΊΠ°ΠΊΠΈΠΌ-ΡΠΎ ΠΏΡΠΈΡΠΈΠ½Π°ΠΌ, Π΄Π°Π²Π°ΠΉΡΠ΅ ΠΏΠΎΡΠΌΠΎΡΡΠΈΠΌ, Π½Π° ΡΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠΏΠ΅ΡΠ΅ΡΡΡΡ, ΡΡΠΎΠ±Ρ Π΄Π°ΠΆΠ΅ Π½Π°Π»ΠΈΡΠΈΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ Π² Π΄Π°Π½Π½ΡΡ Π½Π΅ ΠΏΡΠΈΠ²ΠΎΠ΄ΠΈΠ»ΠΎ ΠΊ Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΌΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΡΠ΅ΠΊΡΡΡΠΈΠΈ.
Π‘ΡΠ΅ΡΡΠΈΠΊ Β«Π³Π»ΡΠ±ΠΈΠ½ΡΒ» ΡΠ΅ΠΊΡΡΡΠΈΠΈ
ΠΡΠΎΡΡΠΎ ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π΅ΠΌ ΡΡΠ΅ΡΡΠΈΠΊ Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡΡ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΡΠ°Π³Π΅ ΡΠ΅ΠΊΡΡΡΠΈΠΈ Π²ΠΏΠ»ΠΎΡΡ Π΄ΠΎ ΠΌΠΎΠΌΠ΅Π½ΡΠ° Π΄ΠΎΡΡΠΈΠΆΠ΅Π½ΠΈΡ ΠΏΡΠ΅Π΄Π΅Π»Π°, ΠΊΠΎΡΠΎΡΡΠΉ ΠΌΡ ΡΡΠΈΡΠ°Π΅ΠΌ Π·Π°Π²Π΅Π΄ΠΎΠΌΠΎ Π½Π΅Π°Π΄Π΅ΠΊΠ²Π°ΡΠ½ΡΠΌ:
WITH RECURSIVE T AS (
SELECT
0 i
...
UNION ALL
SELECT
i + 1
...
WHERE
T.i < 64 -- ΠΏΡΠ΅Π΄Π΅Π»
)
Pro: ΠΡΠΈ ΠΏΠΎΠΏΡΡΠΊΠ΅ Π·Π°ΡΠΈΠΊΠ»ΠΈΠ²Π°Π½ΠΈΡ ΠΌΡ Π²ΡΠ΅ ΡΠ°Π²Π½ΠΎ ΡΠ΄Π΅Π»Π°Π΅ΠΌ Π½Π΅ Π±ΠΎΠ»Π΅Π΅ ΡΠΊΠ°Π·Π°Π½Π½ΠΎΠ³ΠΎ Π»ΠΈΠΌΠΈΡΠ° ΠΈΡΠ΅ΡΠ°ΡΠΈΠΉ Β«Π²Π³Π»ΡΠ±ΡΒ».
Contra: ΠΠ΅Ρ Π³Π°ΡΠ°Π½ΡΠΈΠΈ, ΡΡΠΎ ΠΌΡ Π½Π΅ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ°Π΅ΠΌ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎ ΠΎΠ΄Π½Ρ ΠΈ ΡΡ ΠΆΠ΅ Π·Π°ΠΏΠΈΡΡ β Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π½Π° Π³Π»ΡΠ±ΠΈΠ½Π΅ 15 ΠΈ 25, Π½Ρ ΠΈ Π΄Π°Π»ΡΡΠ΅ Π±ΡΠ΄Π΅Ρ ΠΊΠ°ΠΆΠ΄ΡΠ΅ +10. ΠΠ° ΠΈ ΠΏΡΠΎ Β«Π²ΡΠΈΡΡΒ» Π½ΠΈΠΊΡΠΎ Π½ΠΈΡΠ΅Π³ΠΎ Π½Π΅ ΠΎΠ±Π΅ΡΠ°Π».
Π€ΠΎΡΠΌΠ°Π»ΡΠ½ΠΎ, ΡΠ°ΠΊΠ°Ρ ΡΠ΅ΠΊΡΡΡΠΈΡ Π½Π΅ Π±ΡΠ΄Π΅Ρ Π±Π΅ΡΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΉ, Π½ΠΎ Π΅ΡΠ»ΠΈ Π½Π° ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΡΠ°Π³Π΅ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²ΠΎ Π·Π°ΠΏΠΈΡΠ΅ΠΉ ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π΅ΡΡΡ ΠΏΠΎ ΡΠΊΡΠΏΠΎΠ½Π΅Π½ΡΠ΅, ΠΌΡ Π²ΡΠ΅ Ρ ΠΎΡΠΎΡΠΎ Π·Π½Π°Π΅ΠΌ, ΡΠ΅ΠΌ ΡΡΠΎ ΠΊΠΎΠ½ΡΠ°Π΅ΡΡΡβ¦
Π₯ΡΠ°Π½ΠΈΡΠ΅Π»Ρ Β«ΠΏΡΡΠΈΒ»
ΠΠΎΠΎΡΠ΅ΡΠ΅Π΄Π½ΠΎ Π΄ΠΎΠΏΠΈΡΡΠ²Π°Π΅ΠΌ Π²ΡΠ΅ Π²ΡΡΡΠ΅ΡΠΈΠ²ΡΠΈΠ΅ΡΡ Π½Π°ΠΌ ΠΏΠΎ ΠΏΡΡΠΈ ΡΠ΅ΠΊΡΡΡΠΈΠΈ ΠΈΠ΄Π΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΎΡΡ ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ² Π² ΠΌΠ°ΡΡΠΈΠ², ΠΊΠΎΡΠΎΡΡΠΉ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΠ½ΠΈΠΊΠ°Π»ΡΠ½ΡΠΌ Β«ΠΏΡΡΠ΅ΠΌΒ» Π΄ΠΎ Π½Π΅Π³ΠΎ:
WITH RECURSIVE T AS (
SELECT
ARRAY[id] path
...
UNION ALL
SELECT
path || id
...
WHERE
id <> ALL(T.path) -- Π½Π΅ ΡΠΎΠ²ΠΏΠ°Π΄Π°Π΅Ρ Π½ΠΈ Ρ ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ·
)
Pro: ΠΡΠΈ Π½Π°Π»ΠΈΡΠΈΠΈ ΡΠΈΠΊΠ»Π° Π² Π΄Π°Π½Π½ΡΡ
ΠΌΡ Π°Π±ΡΠΎΠ»ΡΡΠ½ΠΎ ΡΠΎΡΠ½ΠΎ Π½Π΅ ΡΡΠ°Π½Π΅ΠΌ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ ΠΏΠΎΠ²ΡΠΎΡΠ½ΠΎ ΠΎΠ΄Π½Ρ ΠΈ ΡΡ ΠΆΠ΅ Π·Π°ΠΏΠΈΡΡ Π² ΡΠ°ΠΌΠΊΠ°Ρ
ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΡΡΠΈ.
Contra: ΠΠΎ ΠΏΡΠΈ ΡΡΠΎΠΌ ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠ±ΠΎΠΉΡΠΈ, Π±ΡΠΊΠ²Π°Π»ΡΠ½ΠΎ, Π²ΡΠ΅ Π·Π°ΠΏΠΈΡΠΈ, ΡΠ°ΠΊ ΠΈ Π½Π΅ ΠΏΠΎΠ²ΡΠΎΡΠΈΠ²ΡΠΈΡΡ.
ΠΠ³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΠ΅ Π΄Π»ΠΈΠ½Ρ ΠΏΡΡΠΈ
Π§ΡΠΎΠ±Ρ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ ΡΠΈΡΡΠ°ΡΠΈΠΈ Β«Π±Π»ΡΠΆΠ΄Π°Π½ΠΈΡΒ» ΡΠ΅ΠΊΡΡΡΠΈΠΈ Π½Π° Π½Π΅ΠΏΠΎΠ½ΡΡΠ½ΠΎΠΉ Π³Π»ΡΠ±ΠΈΠ½Π΅, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΊΠΎΠΌΠ±ΠΈΠ½ΠΈΡΠΎΠ²Π°ΡΡ Π΄Π²Π° ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠΈΡ ΠΌΠ΅ΡΠΎΠ΄Π°. ΠΠ»ΠΈ, Π΅ΡΠ»ΠΈ Π½Π΅ Ρ ΠΎΡΠΈΠΌ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ Π»ΠΈΡΠ½ΠΈΡ ΠΏΠΎΠ»Π΅ΠΉ, Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΡ ΡΡΠ»ΠΎΠ²ΠΈΠ΅ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ΅Π½ΠΈΡ ΡΠ΅ΠΊΡΡΡΠΈΠΈ ΠΎΡΠ΅Π½ΠΊΠΎΠΉ Π΄Π»ΠΈΠ½Ρ ΠΏΡΡΠΈ:
WITH RECURSIVE T AS (
SELECT
ARRAY[id] path
...
UNION ALL
SELECT
path || id
...
WHERE
id <> ALL(T.path) AND
array_length(T.path, 1) < 10
)
ΠΡΠ±ΠΈΡΠ°ΠΉΡΠ΅ ΡΠΏΠΎΡΠΎΠ± Π½Π° ΡΠ²ΠΎΠΉ Π²ΠΊΡΡ!
ΠΡΡΠΎΡΠ½ΠΈΠΊ: habr.com