DBMS เปเบเปเบฅเบทเปเบญเบเบเบตเปเปเบฎเบฑเบเบงเบฝเบเบขเบนเปเปเบเบซเบผเบฑเบเบเบฒเบเบเบฝเบงเบเบฑเบ - "เบเบงเบเปเบเบปเบฒเบเบญเบเบเปเบญเบเปเบซเปเบเบธเบ, เบชเบฐเบเบฑเปเบเบเปเบญเบเบเบธเบ". เบเบฒเบเบฎเปเบญเบเบเปเบเบญเบเบเปเบฒเบเบเปเปเบเบฝเบเปเบเปเบชเบฒเบกเบฒเบเบเปเบฒเบฅเบปเบเบเบฐเบเบงเบเบเบฒเบเปเบเปเบเบฝเบ, เบชเบทเบเบเปเปเปเบเปเบเบฑเบเบเบฐเบเบฒเบเบญเบเบเบญเบเปเบเปเบเบเปเบเบต, เปเบเปเบเบฑเบ "เบฅเบธเบเบฅเบปเบ" เบเบฒเบเบเปเปเบกเบนเบเบเบฑเบเบซเบกเบปเบ, "เบเบดเบ" เบซเบเปเบงเบเบเบงเบฒเบกเบเปเบฒเบเบตเปเบกเบตเบขเบนเปเบเบฑเบเบซเบกเบปเบ. เบเบฒเบโเบเบปเบโเบเบฑเบโเบฎเบฑเบโเบชเบฒโเบเปเบฒเบโเบเบฒเบ recursion infiniteโ - เบเบงเบฒเบกเบฎเบฑเบเบเบดเบเบเบญเบเบเบญเบเบเบนเปเบเบฑเบเบเบฐเบเบฒเปเบญเบ.
เปเบ PostgreSQL, เบเบงเบฒเบกเบชเบฒเบกเบฒเบเปเบเบเบฒเบเปเบเปเบเบฒเบเบชเบญเบเบเบฒเบก recursive เบเปเบฒเบ WITH RECURSIVE
เบขเปเบฒเบเบฝเบเปเบเบเบชเบญเบเบเบฒเบกเบเปเบณเป
เปเบฅเบฐเบเบฝเบเบชเบดเปเบเบเบตเปเบเปเปเบเปเปเบฒเบเบฑเบ. เบเปเบงเบเบเบงเบฒเบกเบเบฑเบเบเบท, K.O.
เปเบเบเบงเบฒเบกเปเบเบฑเบเบเบดเบ, PostgreSQL เบชเบฐเบซเบเบญเบเบเบฒเบเปเบฎเบฑเบเบงเบฝเบเบซเบผเบฒเบเบขเปเบฒเบเบเบตเปเบเปเบฒเบเบชเบฒเบกเบฒเบเบเปเบฒเปเบเปเปเบเป เบเปเป เบเบณเปเบเป recursion.
เปเบเปเบงเบดเบเบตเบเบฒเบเบเบตเปเปเบเบเบเปเบฒเบเบเบฑเบเปเบเบเบเบทเปเบเบเบฒเบเบเบฑเบเบเบฑเบเบซเบฒ
เบเบฒเบเบเบฑเปเบเบเปเบฒเบเบเบฝเบเปเบเปเบชเบฒเบกเบฒเบเปเบเบดเปเบเบเบฑเบเบซเบฒเบเบฒเบ "เบเปเบฒเบเบเบตเปเปเบเบเบเปเบฒเบเบเบฑเบ". เบเปเบฒเบเบฐเปเบเบปเปเบฒเปเบเปเบเบปเบเบเบปเบงเบขเปเบฒเบเบเบญเบเบชเบฐเบเบฒเบเบฐเบเบฒเบเบเบฑเปเบเบเปเบฒเบงเปเบเบเบปเบเบเบงเบฒเบก
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 เปเบเบ loops
เบชเบปเบกเบกเบธเบเบงเปเบฒเบเบงเบเปเบฎเบปเบฒเบเปเบฒเบฅเบฑเบเบเบฐเปเบเบตเบเบเบฑเบเบงเบฝเบเบเบฒเบเบเบญเบเบเบฒเบเบชเปเบฒเบเบเปเบฒเบเปเบฒเบซเบเปเบฒเบเบตเปเปเบเบฑเบเปเบเปเบเปเบเบฑเบเบซเบกเบปเบเบชเปเบฒเบฅเบฑเบ string '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;
เบเปเบฒเบเปเบเปเปเบเบเปเปเบงเปเบฒเบเปเบญเบเบเบฒเบ recursion เบขเบนเปเบเบตเปเบเบตเป?.. เบเปเบฒเปเบเบปเปเบฒเปเบเป 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;
เปเบเปเปเบเบทเปเบญเบเบเบฒเบเบงเปเบฒเบเบงเบเปเบฎเบปเบฒเบชเบฐเปเบซเบกเบตเบเปเบญเบเบเบฒเบเบซเบปเบงเบเปเปเบเบฑเบเบซเบกเบปเบเบเบฒเบเบเปเปเบเบงเบฒเบกเบฎเบฒเบ, เปเบฅเปเบงเปเบเบฑเบเบซเบเบฑเบเบเบงเบเปเบฎเบปเบฒเบเปเป เปเบเบตเปเบก ID เบเบญเบเบกเบฑเบเปเบชเปเปเบเปเบฅเบฐเบฅเบฒเบเบเบฒเบ เบญเบฑเบเบเบฐเปเบเบกเบฑเบ?
-- ะดะพะฑะฐะฒะธะผ ะฟะพะปะต ั ะพะฑัะธะผ ะธะดะตะฝัะธัะธะบะฐัะพัะพะผ ัะตะผั ะธ ะธะฝะดะตะบั ะฝะฐ ะฝะตะณะพ
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();
เปเบเบเบฑเบเบเบธเบเบฑเบเบเบฒเบเบชเบญเบเบเบฒเบก recursive เบเบฑเบเบซเบกเบปเบเบเบญเบเบเบงเบเปเบฎเบปเบฒเบชเบฒเบกเบฒเบเบซเบผเบธเบเบฅเบปเบเบเบฝเบเปเบเปเบเบตเป:
SELECT
*
FROM
message
WHERE
theme_id = $1;
เปเบเป "เบเบตเบเบเปเบฒเบเบฑเบ" เบเบตเปเปเบเปเปเบฅเปเบง
เบเปเบฒเบเบงเบเปเบฎเบปเบฒเบเปเปเบชเบฒเบกเบฒเบเบเปเบฝเบเปเบเบเบชเปเบฒเบเบเบญเบเบเบฒเบเบเปเปเบกเบนเบเปเบเปเบเปเบงเบเปเบซเบเบเบปเบเบเบฒเบเบขเปเบฒเบ, เปเบซเปเปเบเบดเปเบเบชเบดเปเบเบเบตเปเบเบงเบเปเบฎเบปเบฒเบชเบฒเบกเบฒเบเบญเบตเบเปเบชเปเปเบเบทเปเบญเบงเปเบฒเปเบเบดเบเปเบกเปเบเบงเปเบฒเบเบฒเบเบเบฐเบเบปเบเบเบปเบงเบเบญเบเบเปเปเบเบดเบเบเบฒเบเปเบเบเปเปเบกเบนเบเบเปเปเบเปเปเบเปเบฒเปเบเบชเบนเปเบเบฒเบเปเบญเบตเปเบเบเบทเบเบเบตเปเบเปเปเบชเบดเปเบเบชเบธเบ.
เบเบปเบงเบเบฑเบเบเบงเบฒเบกเปเบฅเบดเบ Recursion
เบเบงเบเปเบฎเบปเบฒเบเบฝเบเปเบเปเปเบเบตเปเบกเบเบฒเบเบเบฑเบเบเบญเบเบซเบผเบฑเบเปเบเบทเปเบญเบฅเบฐเบญเบฑเบเปเบเปเบเปเบฅเบฐเบเบฑเปเบเบเบญเบ recursion เบเบปเบเบเปเบงเบฒเบเบงเบเปเบฎเบปเบฒเบเบฑเบเบฅเบธเบเบญเบเปเบเบเบเปเบฒเบเบฑเบเบเบตเปเบเบงเบเปเบฎเบปเบฒเบเบทเบงเปเบฒเบเปเปเบเบฝเบเบเปเบขเปเบฒเบเบเบฐเปเบเปเบ:
WITH RECURSIVE T AS (
SELECT
0 i
...
UNION ALL
SELECT
i + 1
...
WHERE
T.i < 64 -- ะฟัะตะดะตะป
)
Pro: เปเบเปเบงเบฅเบฒเบเบตเปเบเบงเบเปเบฎเบปเบฒเบเบฐเบเบฒเบเบฒเบก loop, เบเบงเบเปเบฎเบปเบฒเบเบฑเบเบเบฐเปเบฎเบฑเบเบเปเปเปเบเบตเบเบเบญเบเปเบเบเบเปเบฒเบเบฑเบเบเบญเบ iterations "เปเบเบเบงเบฒเบกเปเบฅเบดเบ".
cons: เบเปเปเบกเบตเบเบฒเบเบฎเบฑเบเบเบฐเบเบฑเบเบงเปเบฒเบเบงเบเปเบฎเบปเบฒเบเบฐเบเปเปเบเปเบฒเปเบเบตเบเบเบฒเบเบเบฑเบเบเบถเบเบเบฝเบงเบเบฑเบเบญเบตเบเปเบเบทเปเบญเบซเบเบถเปเบ - เบเบปเบงเบขเปเบฒเบ, เบขเบนเปเบเบตเปเบเบงเบฒเบกเปเบฅเบดเบ 15 เปเบฅเบฐ 25, เปเบฅเบฐเบซเบผเบฑเบเบเบฒเบเบเบฑเปเบเบเบธเบเป +10. เปเบฅเบฐเบเปเปเบกเบตเปเบเบชเบฑเบเบเบฒเบซเบเบฑเบเบเปเบฝเบงเบเบฑเบ "เบเบงเบฒเบกเบเบงเปเบฒเบ".
เบขเปเบฒเบเปเบเบฑเบเบเบฒเบเบเบฒเบ, เบเบฒเบเปเบญเบตเปเบเบเบทเบเบเบฑเปเบเบเปเบฒเบงเบเบฐเบเปเปเปเบเบฑเบเบญเบฑเบเปเบเบฑเบเบเบดเบ, เปเบเปเบเปเบฒเปเบเปเบฅเบฐเบเบฑเปเบเบเบญเบเบเปเบฒเบเบงเบเบเบฑเบเบเบถเบเปเบเบตเปเบกเบเบถเปเบเปเบเบฑเบเปเบฅเบเปเบฅเบ, เบเบงเบเปเบฎเบปเบฒเบเบธเบเบเบปเบเบฎเบนเปเบเบตเบงเปเบฒเบกเบฑเบเบชเบดเปเบเบชเบธเบเบฅเบปเบเปเบเบงเปเบ ...
เบเบนเปเบเบปเบเบเบญเบเบเบญเบ "เปเบชเบฑเปเบเบเบฒเบ"
เบเบงเบเปเบฎเบปเบฒเบชเบฐเบซเบผเบฑเบเบเบฑเบเปเบเบตเปเบกเบเบปเบงเบฅเบฐเบเบธเบงเบฑเบเบเบธเบเบฑเบเปเบปเบเบเบตเปเบเบงเบเปเบฎเบปเบฒเบเบปเบเบขเบนเปเบเบฒเบกเปเบชเบฑเปเบเบเบฒเบเบเบฒเบเปเบญเบตเปเบเบเบทเบเปเบเบปเปเบฒเปเบเบญเบฒเปเบฃ, เปเบเบดเปเบเปเบเบฑเบ โเปเบชเบฑเปเบเบเบฒเบโ เบเบตเปเปเบเบฑเบเปเบญเบเบฐเบฅเบฑเบเบชเบฐเปเบเบฒเบฐ:
WITH RECURSIVE T AS (
SELECT
ARRAY[id] path
...
UNION ALL
SELECT
path || id
...
WHERE
id <> ALL(T.path) -- ะฝะต ัะพะฒะฟะฐะดะฐะตั ะฝะธ ั ะพะดะฝะธะผ ะธะท
)
Pro: เบเปเบฒเบกเบตเบงเบปเบเบเบญเบเปเบเบเปเปเบกเบนเบ, เบเบงเบเปเบฎเบปเบฒเบเบฐเบเปเปเบเปเบฒเปเบเบตเบเบเบฒเบเบเบฑเบเบเบถเบเบเบฝเบงเบเบฑเบเบเปเปเบฒเบเปเบญเบเบขเบนเปเปเบเปเบชเบฑเปเบเบเบฒเบเบเบฝเบงเบเบฑเบ.
cons: เปเบเปเปเบเปเบงเบฅเบฒเบเบฝเบงเบเบฑเบ, เบเบงเบเปเบฎเบปเบฒเบชเบฒเบกเบฒเบ bypass เบเบฑเบเบเบถเบเบเบฑเบเบซเบกเบปเบเบขเปเบฒเบเปเบเปเบเบดเบเปเบเบเบเปเปเบกเบตเบเบฒเบเปเบฎเบฑเบเบเปเปเบฒเบเบปเบงเปเบฎเบปเบฒเปเบญเบ.
เบเบณเบเบฑเบเบเบงเบฒเบกเบเบฒเบงเบเบญเบเปเบชเบฑเปเบเบเบฒเบ
เปเบเบทเปเบญเบซเบผเบตเบเบฅเปเบฝเบเบชเบฐเบเบฒเบเบฐเบเบฒเบเบเบญเบ recursion "wandering" เบขเบนเปเปเบเบเบงเบฒเบกเปเบฅเบดเบเบเบตเปเบเปเปเบชเบฒเบกเบฒเบเปเบเบปเปเบฒเปเบเปเบเป, เบเบงเบเปเบฎเบปเบฒเบชเบฒเบกเบฒเบเบชเบปเบกเบเบปเบเบชเบญเบเบงเบดเบเบตเบเบฒเบเบเบตเปเบเปเบฒเบเบกเบฒ. เบซเบผเบท, เบเปเบฒเบเบงเบเปเบฎเบปเบฒเบเปเปเบเปเบญเบเบเบฒเบเบชเบฐเบซเบเบฑเบเบชเบฐเบซเบเบนเบเบเปเบญเบเบเปเปเบกเบนเบเบเบตเปเบเปเปเบเปเบฒเปเบเบฑเบ, เปเบชเบตเบกเปเบเบทเปเบญเบเปเบเบชเปเบฒเบฅเบฑเบเบเบฒเบเบชเบทเบเบเปเป recursion เบเปเบงเบเบเบฒเบเบเบฒเบเบเบฐเปเบเบเบญเบเบเบงเบฒเบกเบเบฒเบงเบเบญเบเปเบชเบฑเปเบเบเบฒเบ:
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
)
เปเบฅเบทเบญเบเบงเบดเบเบตเบเบฒเบเปเบเบทเปเบญเบฅเบปเบเบเบฒเบเบเบญเบเบเปเบฒเบ!
เปเบซเบผเปเบเบเปเปเบกเบนเบ: www.habr.com