เช เชธเชเชฆเชฐเซเชญเชฎเชพเช DBMS เชธเชฎเชพเชจ เชธเชฟเชฆเซเชงเชพเชเชคเซ เชชเชฐ เชเชพเชฎ เชเชฐเซ เชเซ - "เชคเซเชเช เชฎเชจเซ เชเซเชฆเชตเชพเชจเซเช เชเชนเซเชฏเซเช, เชคเซเชฅเซ เชนเซเช เชเซเชฆเซเช". เชคเชฎเชพเชฐเซ เชตเชฟเชจเชเชคเซ เชฎเชพเชคเซเชฐ เชชเชกเซเชถเซ เชชเซเชฐเชเซเชฐเชฟเชฏเชพเชเชจเซ เชงเซเชฎเซเช เชเชฐเซ เชถเชเชคเซ เชจเชฅเซ, เชธเชคเชค เชชเซเชฐเซเชธเซเชธเชฐ เชธเชเชธเชพเชงเชจเซ เชฒเซ เชเซ, เชชเชฃ เชธเชฎเชเซเชฐ เชกเซเชเชพเชฌเซเชเชจเซ "เชเซเชกเซ" เช
เชจเซ เชฌเชงเซ เชเชชเชฒเชฌเซเชง เชฎเซเชฎเชฐเซเชจเซ "เชเชพเช" เชชเชฃ เชถเชเซ เชเซ. เชคเซเชฅเซ เช
เชจเชเชค เชชเซเชจเชฐเชพเชตเชฐเซเชคเชจ เชธเชพเชฎเซ เชฐเชเซเชทเชฃ - เชตเชฟเชเชพเชธเชเชฐเซเชคเชพเชจเซ เชชเซเชคเชพเชจเซ เชเชตเชพเชฌเชฆเชพเชฐเซ.
PostgreSQL เชฎเชพเช, เชฆเซเชตเชพเชฐเชพ เชชเซเชจเชฐเชพเชตเชฐเซเชคเชฟเชค เชชเซเชฐเชถเซเชจเซเชจเซ เชเชชเชฏเซเช เชเชฐเชตเชพเชจเซ เชเซเชทเชฎเชคเชพ WITH RECURSIVE
เชชเซเชจเชฐเชพเชตเชฐเซเชคเชฟเชค เชชเซเชฐเชถเซเชจเซ เชฒเชเชถเซ เชจเชนเซเช
เช เชจเซ เชจเซเชจ-เชฐเชฟเชเชฐเซเชธเชฟเชต เชฒเชเซ. เชเชชเชจเซ, เชคเชฎเชพเชฐเชพ K.O.
เชนเชเซเชเชคเชฎเชพเช, 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;
เชชเชฐเชเชคเซ เชเชพเชฐเชฃ เชเซ เชเชชเชฃเชจเซ เชนเชเชฎเซเชถเชพ เชฐเซเช เชธเชเชฆเซเชถเชฎเชพเชเชฅเซ เชธเชฎเชเซเชฐ เชตเชฟเชทเชฏเชจเซ เชเชฐเซเชฐ เชนเซเชฏ เชเซ, เชคเซ เชชเชเซ เชเชชเชฃเซ เชเซเชฎ เชจเชนเซเช เชฆเชฐเซเช เชเชจเซเชเซเชฐเซเชฎเชพเช เชคเซเชจเซเช 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();
เชนเชตเซ เช
เชฎเชพเชฐเซ เชเชเซ เชชเซเชจเชฐเชพเชตเชฐเซเชคเชฟเชค เชเซเชตเซเชฐเซ เชฎเชพเชคเซเชฐ เชเชฎเชพเช เชเชเชพเชกเซ เชถเชเชพเชฏ เชเซ:
SELECT
*
FROM
message
WHERE
theme_id = $1;
เชฒเชพเชเซ "เชฎเชฐเซเชฏเชพเชฆเชพ" เชจเซ เชเชชเชฏเซเช เชเชฐเซ
เชเซ เชเชชเชฃเซ เชเซเช เชเชพเชฐเชฃเซเชธเชฐ เชกเซเชเชพเชฌเซเชเชจเซเช เชฎเชพเชณเชเซเช เชฌเชฆเชฒเชตเชพเชฎเชพเช เช เชธเชฎเชฐเซเชฅ เชนเซเชเช, เชคเซ เชเชพเชฒเซ เชเซเชเช เชเซ เชเชชเชฃเซ เชถเซเชจเชพ เชชเชฐ เชเชงเชพเชฐ เชฐเชพเชเซ เชถเชเซเช เชเซเชฅเซ เชกเซเชเชพเชฎเชพเช เชญเซเชฒเชจเซ เชนเชพเชเชฐเซ เชชเชฃ เช เชจเชเชค เชชเซเชจเชฐเชพเชตเชฐเซเชคเชจ เชคเชฐเชซ เชฆเซเชฐเซ เชจ เชเชพเชฏ.
เชฐเชฟเชเชฐเซเชเชจ เชกเซเชชเซเชฅ เชเชพเชเชจเซเชเชฐ
เช เชฎเซ เชฆเชฐเซเช เชชเซเชจเชฐเชพเชตเชฐเซเชคเชฟเชค เชชเชเชฒเชพ เชชเชฐ เชเชพเชเชจเซเชเชฐเชจเซ เชเช เชตเชกเซ เชตเชงเชพเชฐเซเช เชเซเช เชเซเชฏเชพเช เชธเซเชงเซ เช เชฎเซ เชเชตเซ เชฎเชฐเซเชฏเชพเชฆเชพ เชธเซเชงเซ เชชเชนเซเชเชเซ เชจ เชเชเช เชเซเชจเซ เช เชฎเซ เชฆเซเชเซเชคเซ เชฐเซเชคเซ เช เชชเซเชฐเชคเซ เชฎเชพเชจเซเช เชเซเช:
WITH RECURSIVE T AS (
SELECT
0 i
...
UNION ALL
SELECT
i + 1
...
WHERE
T.i < 64 -- ะฟัะตะดะตะป
)
เชชเซเชฐเซ: เชเซเชฏเชพเชฐเซ เชเชชเชฃเซ เชฒเซเชช เชเชฐเชตเชพเชจเซ เชชเซเชฐเชฏเชพเชธ เชเชฐเซเช เชเซเช, เชคเซเชฏเชพเชฐเซ เชชเชฃ เชเชชเชฃเซ "เชเชเชกเชพเชฃเชฎเชพเช" เชชเซเชจเชฐเชพเชตเชฐเซเชคเชจเซเชจเซ เชจเชฟเชฐเซเชฆเชฟเชทเซเช เชฎเชฐเซเชฏเชพเชฆเชพ เชเชฐเชคเชพเช เชตเชงเซ เชจเชนเซเช เชเชฐเซเช.
เชเซเชคเชฐเชชเชฟเชเชกเซเชเช: เชคเซเชฏเชพเช เชเซเช เชเซเชฐเซเชเชเซ เชจเชฅเซ เชเซ เช
เชฎเซ เชคเซ เช เชฐเซเชเซเชฐเซเชก เชชเชฐ เชซเชฐเซเชฅเซ เชชเซเชฐเชเซเชฐเชฟเชฏเชพ เชเชฐเซเชถเซเช เชจเชนเซเช - เชเชฆเชพเชนเชฐเชฃ เชคเชฐเซเชเซ, 15 เช
เชจเซ 25 เชจเซ เชเชเชกเชพเชเช, เช
เชจเซ เชชเชเซ เชฆเชฐเซเช +10. เช
เชจเซ เชเซเชเช "เชชเชนเซเชณเชพเช" เชตเชฟเชถเซ เชเชเชเชชเชฃ เชตเชเชจ เชเชชเซเชฏเซเช เชจเชฅเซ.
เชเชชเชเชพเชฐเชฟเช เชฐเซเชคเซ, เชเชตเชพ เชชเซเชจเชฐเชพเชตเชฐเซเชคเชจ เช เชจเชเชค เชนเชถเซ เชจเชนเซเช, เชชเชฐเชเชคเซ เชเซ เชฆเชฐเซเช เชชเชเชฒเชพ เชชเชฐ เชฐเซเชเซเชฐเซเชกเซเชธเชจเซ เชธเชเชเซเชฏเชพ เชเชกเชชเชฅเซ เชตเชงเซ เชเซ, เชคเซ เชเชชเชฃเซ เชฌเชงเชพ เชธเชพเชฐเซ เชฐเซเชคเซ เชเชพเชฃเซเช เชเซเช เชเซ เชคเซ เชเซเชตเซ เชฐเซเชคเซ เชธเชฎเชพเชชเซเชค เชฅเชพเชฏ เชเซ ...
"เชชเชพเชฅ" เชจเชพ เชตเชพเชฒเซ
เช เชฎเซ เชฐเชฟเชเชฐเซเชเชจ เชชเชพเชฅ เชธเชพเชฅเซ เชฎเชณเซเชฒเชพ เชคเชฎเชพเชฎ เชเชฌเซเชเซเชเซเช เชเชณเชเชเชฐเซเชคเชพเชเชจเซ เช เชฎเซ เชตเซเชเชฒเซเชชเชฟเช เชฐเซเชคเซ เชเชฐเซเชฎเชพเช เชเชฎเซเชฐเซเช เชเซเช, เชเซ เชคเซเชจเชพ เชฎเชพเชเซ เชเช เช เชจเชจเซเชฏ "เชชเชพเชฅ" เชเซ:
WITH RECURSIVE T AS (
SELECT
ARRAY[id] path
...
UNION ALL
SELECT
path || id
...
WHERE
id <> ALL(T.path) -- ะฝะต ัะพะฒะฟะฐะดะฐะตั ะฝะธ ั ะพะดะฝะธะผ ะธะท
)
เชชเซเชฐเซ: เชเซ เชกเซเชเชพเชฎเชพเช เชเซเช เชเชเซเชฐ เชนเซเชฏ, เชคเซ เช
เชฎเซ เชคเซ เช เชชเชพเชฅเชจเซ เช
เชเชฆเชฐ เชเช เช เชฐเซเชเซเชฐเซเชกเชจเซ เชตเชพเชฐเชเชตเชพเชฐ เชชเซเชฐเชเซเชฐเชฟเชฏเชพ เชเชฐเซเชถเซเช เชจเชนเซเช.
เชเซเชคเชฐเชชเชฟเชเชกเซเชเช: เชชเชฐเชเชคเซ เชคเซ เช เชธเชฎเชฏเซ, เชเชชเชฃเซ เชเชชเชฃเซ เชเชพเชคเชจเซ เชชเซเชจเชฐเชพเชตเชฐเซเชคเชจ เชเชฐเซเชฏเชพ เชตเชฟเชจเชพ เชถเชพเชฌเซเชฆเชฟเช เชฐเซเชคเซ เชคเชฎเชพเชฎ เชฐเซเชเซเชฐเซเชกเซเชธเชจเซ เชฌเชพเชฏเชชเชพเชธ เชเชฐเซ เชถเชเซเช เชเซเช.
เชชเชพเชฅ เชฒเชเชฌเชพเช เชฎเชฐเซเชฏเชพเชฆเชพ
เช เชเชฎเซเชฏ เชเชเชกเชพเชฃเชฎเชพเช เชชเซเชจเชฐเชพเชตเชฐเซเชคเชฟเชค "เชญเชเชเชคเชพ" เชจเซ เชชเชฐเชฟเชธเซเชฅเชฟเชคเชฟเชจเซ เชเชพเชณเชตเชพ เชฎเชพเชเซ, เช เชฎเซ เช เชเชพเชเชจเซ เชฌเซ เชชเชฆเซเชงเชคเชฟเชเชจเซ เชเซเชกเซ เชถเชเซเช เชเซเช. เช เชฅเชตเชพ, เชเซ เชเชชเชฃเซ เชฌเชฟเชจเชเชฐเซเชฐเซ เชเซเชทเซเชคเซเชฐเซเชจเซ เชธเชฎเชฐเซเชฅเชจ เชเชชเชตเชพ เชฎเชพเชเชเชคเชพ เชจ เชนเซเชฏ, เชคเซ เชชเชพเชฅ เชฒเชเชฌเชพเชเชจเชพ เช เชเชฆเชพเช เชธเชพเชฅเซ เชชเซเชจเชฐเชพเชตเชฐเซเชคเชจ เชเชพเชฒเซ เชฐเชพเชเชตเชพ เชฎเชพเชเซเชจเซ เชถเชฐเชคเชจเซ เชชเซเชฐเช เชฌเชจเชพเชตเซ:
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