เปเบเปเบฅเบฐเปเบฅเบเบฐ, เบงเบฝเบเบเบฒเบเบเบญเบเบเบฒเบเบเบปเปเบเบซเบฒเบเปเปเบกเบนเบเบเบตเปเบเปเบฝเบงเบเปเบญเบเปเบเบเปเบเปเบเบธเบเบเบญเบเบเบฐเปเบเปเบเบตเบเบเบทเปเบ. เบเบปเบเบเปเบงเบฒเบเบงเบเปเบฎเบปเบฒเปเบเปเบฎเบฑเบเบเปเบฒเบเบงเบเบเบฑเบเบซเบกเบปเบเบเบตเปเบเปเบฒเบเบปเบเปเบงเปเบเบญเบเบเบฑเบเบเบถเบ.
เบเบปเบงเบขเปเบฒเบ "เบเบตเบงเบดเบเบเบดเบ" เบเบตเปเบชเบธเบเปเบกเปเบเบเบฒเบเบชเบฐเปเบเบ 20 เบเบฑเบเบซเบฒเปเบเบปเปเบฒเปเบเปเบเบตเปเบชเบธเบ, เบฅเบฒเบเบเบทเป เปเบโเบเบฑเบโเบเบตโเบฅเบฒเบโเบเบทเปโเบเบญเบโเบเบฐโเบเบฑเบโเบเบฒเบโ (เบเบปเบงเบขเปเบฒเบ, เบเบฒเบเปเบเบซเบเบถเปเบเบเบฐเปเบเบ). เบชเปเบฒเบฅเบฑเบเบเบฒเบเบเบธเปเบกเบเบญเบเบเปเบฒเบเป "dashboards" เบเบตเปเบกเบตเบเบปเบเบชเบฐเบซเบผเบธเบเบชเบฑเปเบเปเบเบญเบเบเบทเปเบเบเบตเปเปเบฎเบฑเบเบงเบฝเบ, เบซเบปเบงเบเปเปเบเบตเปเบเปเบฒเบเบเบทเบเบฑเบเปเบกเปเบเบเปเบญเบเบเบฒเบเปเบฅเบทเปเบญเบเป.
เปเบเบเบปเบเบเบงเบฒเบกเบเบตเปเบเบงเบเปเบฎเบปเบฒเบเบฐเปเบเบดเปเบเบเบฒเบเบเบฐเบเบดเบเบฑเบเปเบ PostgreSQL เบเบญเบเบเบฒเบเปเบเปเปเบ "naive" เบชเปเบฒเบฅเบฑเบเบเบฑเบเบซเบฒเบเบฑเปเบเบเปเบฒเบง, เปเบเบฑเบ "smarter" เปเบฅเบฐ algorithm เบชเบฐเบฅเบฑเบเบชเบฑเบเบเปเบญเบเบซเบผเบฒเบ. "loop" เปเบ SQL เบเบตเปเบกเบตเปเบเบทเปเบญเบเปเบเบญเบญเบเบเบฒเบเบเปเปเบกเบนเบเบเบตเปเบเบปเบเปเบซเบฑเบ, เบเบถเปเบเบชเบฒเบกเบฒเบเปเบเบฑเบเบเบฐเปเบซเบเบเบเบฑเบเบเบฒเบเบเบฑเบเบเบฐเบเบฒเบเบปเปเบงเปเบเปเบฅเบฐเบชเปเบฒเบฅเบฑเบเบเบฒเบเบเปเบฒเปเบเปเปเบเบเปเบฅเบฐเบเบตเบเบตเปเบเปเบฒเบเบเบทเบเบฑเบเบญเบทเปเบเป.
เปเบซเปเปเบฎเบปเบฒเปเบญเบปเบฒเบเบธเบเบเปเปเบกเบนเบเบเบฒเบเบเบปเบเบชเบญเบเบเบฒเบ
CREATE INDEX ON task(owner_id, task_date, id);
-- ะฐ ััะฐััะน - ัะดะฐะปะธะผ
DROP INDEX task_owner_id_task_date_idx;
เบเบฒเบกโเบเบตเปโเปเบเปโเบเบดเบ, เบเบฑเปเบโเบเบฑเปเบโเบเบถเปเบโเบเบฝเบ
เบเปเบฒเบญเบดเบ, เปเบซเปเปเบฎเบปเบฒเปเบเปเบกเบชเบฐเบเบฑเบเบเบตเปเบเปเบฒเบเบเบฒเบเบเบตเปเบชเบธเบเบเบญเบเบเปเบฒเบฎเปเบญเบเบเป, เบเปเบฒเบ IDs เบเบญเบเบเบฑเบเบชเบฐเปเบเบ
SELECT
*
FROM
task
WHERE
owner_id = ANY('{1,2,4,8,16,32,64,128,256,512}'::integer[])
ORDER BY
task_date, id
LIMIT 20;
เบเบงเบฒเบกเปเบชเบเปเบชเบปเปเบฒเปเบฅเบฑเบเบเปเบญเบ - เบเบงเบเปเบฎเบปเบฒเบชเบฑเปเบเบเบฝเบเปเบเป 20 เบเบฑเบเบเบถเบ, เปเบเป Index Scan เบชเบปเปเบเบเบทเบเบกเบฑเบเปเบซเปเบเบงเบเปเบฎเบปเบฒ 960 เปเบชเบฑเปเบ, เปเบเบดเปเบเบซเบผเบฑเบเบเบฒเบเบเบฑเปเบเบเปเปเบเปเบญเบเปเบเปเบเบฑเบเบฎเบฝเบ ... เปเบซเปเบเบฐเบเบฒเบเบฒเบกเบญเปเบฒเบเบซเบเปเบญเบเบฅเบปเบ.
unnest + ARRAY
เบเบฒเบเบเบดเบเบฒเบฅเบฐเบเบฒเบเปเบฒเบญเบดเบเบเบตเปเบเบฐเบเปเบงเบเปเบซเปเบเบงเบเปเบฎเบปเบฒเปเบกเปเบเบเปเบฒเบเบงเบเปเบฎเบปเบฒเบเปเบญเบเบเบฒเบ เบเบฝเบเปเบเป 20 เบเบฑเบ เบเบฑเบเบเบถเบ, เบซเบผเบฑเบเบเบฒเบเบเบฑเปเบเบเบฝเบเปเบเปเบญเปเบฒเบ เบเปเปเปเบเบตเบ 20 เบเบฑเบเบฎเบฝเบเบเบฒเบกเบฅเบณเบเบฑเบเบเบฝเบงเบเบฑเบเบชเบณเบฅเบฑเบเปเบเปเบฅเบฐเบญเบฑเบ เบเบฐเปเบ. เบเบต, เบเบฑเบโเบเบฐโเบเบตโเบเบตเปโเปเบซเบกเบฒเบฐโเบชเบปเบกโ (owner_id, task_date, id) เบเบงเบเปเบฎเบปเบฒเบกเบต.
เปเบซเปเปเบเปเบเบปเบเปเบเบเบฝเบงเบเบฑเบเบชเปเบฒเบฅเบฑเบเบเบฒเบเบชเบฐเบเบฑเบเปเบฅเบฐ "เปเบเปเปเบเบปเปเบฒเปเบเปเบเบเบฑเบ" เบเบฑเบเบเบถเบเบเบฒเบเบฐเบฅเบฒเบเบเบฐเบชเบปเบกเบเบฐเบชเบฒเบ, เปเบโเบเบฒโเบเบฐโเปเบเบฑเบโ ARRAY()
:
WITH T AS (
SELECT
unnest(ARRAY(
SELECT
t
FROM
task t
WHERE
owner_id = unnest
ORDER BY
task_date, id
LIMIT 20 -- ะพะณัะฐะฝะธัะธะฒะฐะตะผ ััั...
)) r
FROM
unnest('{1,2,4,8,16,32,64,128,256,512}'::integer[])
)
SELECT
(r).*
FROM
T
ORDER BY
(r).task_date, (r).id
LIMIT 20; -- ... ะธ ััั - ัะพะถะต
เปเบญเป, เบเบตเบเบงเปเบฒเปเบฅเปเบง! เปเบงเบเบงเปเบฒ 40% เปเบฅเบฐเบเปเปเบกเบนเบเปเปเบญเบเบเบงเปเบฒ 4.5 เปเบเบปเปเบฒ เบเปเบญเบเบเปเบญเบเบญเปเบฒเบเบกเบฑเบ.
เบงเบฑเบเบชเบฐเบเบธเบเบญเบเบเบฑเบเบเบถเบเบเบฒเบเบฐเบฅเบฒเบเบเปเบฒเบ CTEเปเบซเปเบเปเบญเบเบเบถเบเบเบนเบเบเบงเบฒเบกเบชเบปเบเปเบเบเบญเบเปเบเบปเปเบฒเบเบฑเบเบเบงเบฒเบกเบเบดเบเบเบตเปเบงเปเบฒ เปเบโเบเบฒเบโเบเปโเบฅเบฐโเบเบต เบเบงเบฒเบกเบเบฐเบเบฒเบเบฒเบกเบเบตเปเบเบฐเปเบฎเบฑเบเบงเบฝเบเบเบฑเบเบเบตเบเบฑเบเปเบเบเบฑเบเบเบฒเบเบชเบฐเบซเบเบฒเบกเบเบญเบเบเบฑเบเบเบถเบเบซเบผเบฑเบเบเบฒเบเบเบฒเบเบเบญเบเบซเบฒเบกเบฑเบเบขเบนเปเปเบ subquery, เปเบเบเบเปเปเบกเบตเบเบฒเบ "เบซเปเป" เบกเบฑเบเบขเบนเปเปเบ CTE, เบชเบฒเบกเบฒเบเบเปเบฒเปเบเบชเบนเปเบเบฒเบ. "เบเบนเบ" InitPlan เบญเบฑเบเบเบฒเบชเปเบงเบเบเบฑเบเบเปเบฒเบเบงเบเบเปเบญเบเบเปเปเบกเบนเบเบเบฝเบงเบเบฑเบเปเบซเบผเบปเปเบฒเบเบตเป:
SELECT
((
SELECT
t
FROM
task t
WHERE
owner_id = 1
ORDER BY
task_date, id
LIMIT 1
).*);
Result (cost=4.77..4.78 rows=1 width=16) (actual time=0.063..0.063 rows=1 loops=1)
Buffers: shared hit=16
InitPlan 1 (returns $0)
-> Limit (cost=0.42..1.19 rows=1 width=48) (actual time=0.031..0.032 rows=1 loops=1)
Buffers: shared hit=4
-> Index Scan using task_owner_id_task_date_id_idx on task t (cost=0.42..387.57 rows=500 width=48) (actual time=0.030..0.030 rows=1 loops=1)
Index Cond: (owner_id = 1)
Buffers: shared hit=4
InitPlan 2 (returns $1)
-> Limit (cost=0.42..1.19 rows=1 width=48) (actual time=0.008..0.009 rows=1 loops=1)
Buffers: shared hit=4
-> Index Scan using task_owner_id_task_date_id_idx on task t_1 (cost=0.42..387.57 rows=500 width=48) (actual time=0.008..0.008 rows=1 loops=1)
Index Cond: (owner_id = 1)
Buffers: shared hit=4
InitPlan 3 (returns $2)
-> Limit (cost=0.42..1.19 rows=1 width=48) (actual time=0.008..0.008 rows=1 loops=1)
Buffers: shared hit=4
-> Index Scan using task_owner_id_task_date_id_idx on task t_2 (cost=0.42..387.57 rows=500 width=48) (actual time=0.008..0.008 rows=1 loops=1)
Index Cond: (owner_id = 1)
Buffers: shared hit=4"
InitPlan 4 (returns $3)
-> Limit (cost=0.42..1.19 rows=1 width=48) (actual time=0.009..0.009 rows=1 loops=1)
Buffers: shared hit=4
-> Index Scan using task_owner_id_task_date_id_idx on task t_3 (cost=0.42..387.57 rows=500 width=48) (actual time=0.009..0.009 rows=1 loops=1)
Index Cond: (owner_id = 1)
Buffers: shared hit=4
เบเบฑเบเบเบถเบเบเบฝเบงเบเบฑเบเปเบเปเบเบทเบ "เปเบเบดเปเบ" 4 เปเบเบทเปเบญ ... เบเบปเบเบเปเบงเบฒ PostgreSQL 11, เบเบถเบเบเบดเบเปเบฒเบเบตเปเปเบเบตเบเบเบถเปเบเปเบเบฑเบเบเบปเบเบเบฐเบเบด, เปเบฅเบฐเบเบฒเบเปเบเปเปเบเปเบกเปเบเปเบเบทเปเบญ "เบซเปเป" เบกเบฑเบเบขเบนเปเปเบ CTE, เปเบเบดเปเบเปเบเบฑเบเบเบญเบเปเบเบเบเปเบฒเบเบฑเบเบขเปเบฒเบเปเบเปเบเบดเบเบชเปเบฒเบฅเบฑเบ optimizer เปเบเบชเบฐเบเบฑเบเปเบซเบผเบปเปเบฒเบเบตเป.
เบเบฑเบเบชเบฐเบชเบปเบก Recursive
เปเบเบชเบฐเบเบฑเบเบเบตเปเบเปเบฒเบเบกเบฒ, เบเบงเบเปเบฎเบปเบฒเบญเปเบฒเบเบเบฑเบเบซเบกเบปเบ 200 เปเบชเบฑเปเบ เบชเปเบฒเบฅเบฑเบ sake เบเบญเบเบเบงเบฒเบกเบเปเบญเบเบเบฒเบ 20. เบเปเปเปเบกเปเบ 960, เปเบเปเปเบเบดเบเปเบกเปเบเบงเปเบฒเบซเบเปเบญเบ - เบกเบฑเบเปเบเบฑเบเปเบเปเบเปเบเป?
เบฅเบญเบเปเบเปเบเบงเบฒเบกเบฎเบนเปเบเบตเปเปเบฎเบปเบฒเบเปเบญเบเบเบฒเบ เบฅเบงเบก 20 เบเบฑเบเบเบถเบ. เบเบฑเปเบเปเบกเปเบ, เบเบงเบเปเบฎเบปเบฒเบเบฐเปเบฎเบฑเบเบเปเปเบฒเบเบฒเบเบญเปเบฒเบเบเปเปเบกเบนเบเปเบเบปเปเบฒเบเบฑเปเบเบเบปเบเบเปเบงเบฒเบเบงเบเปเบฎเบปเบฒเบเบฑเบเบฅเบธเบเปเบฒเบเบงเบเบเบตเปเบเบงเบเปเบฎเบปเบฒเบเปเบญเบเบเบฒเบ.
เบเบฑเปเบเบเบญเบเบเบต 1: เปเบฅเบตเปเบกเบเบปเปเบเบฅเบฒเบเบเบฒเบ
เปเบเปเบเบญเบ, เบเบฑเบเบเบตเบฅเบฒเบเบเบทเป "เปเบเบปเปเบฒเบซเบกเบฒเบ" เบเบญเบเบเบงเบเปเบฎเบปเบฒเบเบญเบ 20 เบเบฑเบเบเบถเบเบเบงเบเปเบฅเบตเปเบกเบเบปเปเบเบเปเบงเบเบเบฑเบเบเบถเบ "เบเปเบฒเบญเบดเบ" เบชเปเบฒเบฅเบฑเบเบซเบเบถเปเบเปเบเบฅเบฐเบซเบฑเบ owner_id เบเบญเบเบเบงเบเปเบฎเบปเบฒ. เปเบเบฒเบฐเบชเบฐเบเบฑเปเบ, เบเปเบฒเบญเบดเบเบเบงเบเปเบฎเบปเบฒเบเบฐเบเบญเบเบซเบฒเบชเบดเปเบเบเบฑเปเบเบเปเบฒเบง "เบเปเบฒเบญเบดเบ" เบชเปเบฒเบฅเบฑเบเปเบเปเบฅเบฐเบเบฐเปเบ เปเบฅเบฐเปเบเบตเปเบกเบกเบฑเบเปเบเบปเปเบฒเปเบเบเบฑเบเบเบตเบฅเบฒเบเบเบทเป, เบเบฑเบเบฎเบฝเบเบเบฒเบกเบฅเปเบฒเบเบฑเบเบเบตเปเบเบงเบเปเบฎเบปเบฒเบเปเบญเบเบเบฒเบ - (task_date, id).
เบเบฑเปเบเบเบญเบเบเบต 2: เบเบญเบเบซเบฒเบฅเบฒเบเบเบฒเบ "เบเปเปเปเบ".
เปเบเบเบฑเบเบเบธเบเบฑเบเบเปเบฒเบเบงเบเปเบฎเบปเบฒเปเบญเบปเบฒเบเบฒเบเปเบเบปเปเบฒเบเปเบฒเบญเบดเบเบเบฒเบเบเบฑเบเบเบตเบฅเบฒเบเบเบทเปเบเบญเบเบเบงเบเปเบฎเบปเบฒเปเบฅเบฐเปเบฅเบตเปเบกเบเบปเปเบ "เบเปเบฒเบง" เบเปเปเปเบเบเบฒเบกเบเบฑเบเบเบฐเบเบต เบฎเบฑเบเบชเบฒเบฅเบฐเบซเบฑเบ owner_id, เบซเบผเบฑเบเบเบฒเบเบเบฑเปเบเบเบฑเบเบเบถเบเบเบฑเบเบซเบกเบปเบเบเบตเปเบเบปเบเปเบซเบฑเบเปเบกเปเบเปเบเปเบเบญเบเบญเบฑเบเบเปเปเปเบเปเบเบเบฒเบเบเบฑเบเปเบฅเบทเบญเบเบเบปเบเปเบเปเบฎเบฑเบ. เปเบเปเบเบญเบ, เบเบฝเบเปเบเป เบเบปเบเบเปเบงเบฒเบเบงเบเปเบฎเบปเบฒเบเปเบฒเบกเบเบตเบเบปเปเบ เปเบเบปเปเบฒเบเบตเบชเบญเบเปเบเบเบฑเบเบเบตเบฅเบฒเบเบเบทเป.
เบเปเบฒเบกเบฑเบเบเบฒเบเบปเบเบงเปเบฒเบเบงเบเปเบฎเบปเบฒ "เบเปเบฒเบก" เบเบฑเบเบเบถเบเบเบตเบชเบญเบ, เบซเบผเบฑเบเบเบฒเบเบเบฑเปเบ เบเปเปเบเบงเบฒเบกเบชเบธเบเบเปเบฒเบเบเบตเปเบญเปเบฒเบเบเบงเบเบเบฐเบเบทเบเปเบเบตเปเบกเปเบชเปเบเบฑเบเบเบตเบฅเบฒเบเบเบทเปเปเบเบเบเบตเปเบเบฐเปเบเบฑเบเบญเบฑเบเบเปเบฒเบญเบดเบ (เบเบฑเบ owner_id เบเบฝเบงเบเบฑเบ), เบซเบผเบฑเบเบเบฒเบเบเบฑเปเบเบเบงเบเปเบฎเบปเบฒเบเบฑเบเบฎเบฝเบเบเบฑเบเบเบตเบฅเบฒเบเบเบทเปเบญเบตเบเปเบเบทเปเบญเบซเบเบถเปเบ.
เบเบฑเปเบเปเบกเปเบ, เบเบงเบเปเบฎเบปเบฒเบชเบฐเปเบซเบกเบตเปเบเปเบฎเบฑเบเบงเปเบฒเบเบฑเบเบเบตเบฅเบฒเบเบเบทเปเบเปเปเบกเบตเบซเบผเบฒเบเบเปเบงเบฒเบซเบเบถเปเบเบฅเบฒเบเบเบฒเบเบชเปเบฒเบฅเบฑเบเปเบเปเบฅเบฐเบเบฐเปเบ (เบเปเบฒเบฅเบฒเบเบเบฒเบเบซเบกเบปเบเปเบเปเบฅเบฐเบเบงเบเปเบฎเบปเบฒเบเปเป "เบเปเบฒเบก", เบซเบผเบฑเบเบเบฒเบเบเบฑเปเบเบฅเบฒเบเบเบฒเบเบเปเบฒเบญเบดเบเบเบฒเบเบเบฑเบเบเบตเบฅเบฒเบเบเบทเปเบเบฐเบซเบฒเบเปเบเปเบฅเบฐเบเปเปเบกเบตเบซเบเบฑเบเบเบฐเปเบเบตเปเบก. ), เปเบฅเบฐเบเบงเบเปเบเบปเบฒ เบเบฑเบเบฎเบฝเบเบชเบฐ เปเปเบต เปเบเบฅเปเบฒเบเบฑเบเบเบฑเปเบเบเบฑเบเบเบถเปเบเบเบญเบเบฅเบฐเบซเบฑเบเบเปเบฒเบฎเปเบญเบเบชเบฐเบซเบกเบฑเบ (task_date, id).
เบเบฑเปเบเบเบญเบเบเบต 3: เบเบฒเบเบเบฑเปเบเบเบญเบเปเบฅเบฐ "เบเบฐเบซเบเบฒเบ" เบเบฑเบเบเบถเบ
เปเบเบเบฒเบเปเบเบงเบเบญเบเบเบฒเบเบเบฑเบเปเบฅเบทเบญเบ recursive เบเบญเบเบเบงเบเปเบฎเบปเบฒ, เบเบฒเบเบเบฑเบเบเบถเบ rv
เบเบทเบเบเปเปเบฒเบเบฑเบ - เบเปเบฒเบญเบดเบเบเบงเบเปเบฎเบปเบฒเบเบญเบเบซเบฒเปเบเบฑเปเบ "เบเปเบฒเบกเบเบฒเบเปเบเบเบเบญเบเบฅเบฒเบเบเบฒเบเบเบต 2 เบเบญเบเบฅเบฒเบเบเบฒเบ", เปเบฅเบฐเบซเบผเบฑเบเบเบฒเบเบเบฑเปเบเบเบปเบเปเบเบเบกเบฑเบเปเบเบฑเบเบญเบฑเบเบเบฑเบเบเบต 1 เบเบฒเบเบเบฑเบเบเบตเบฅเบฒเบเบเบทเป. เบเบฑเปเบเบเบฑเปเบเบเบฒเบเบเบฐเบเบปเบเบเบปเบงเบเบฑเปเบเบเปเบฒเบญเบดเบเบเปเบญเบเปเบเปเบฎเบฑเบเบเบฒเบเบเบฑเปเบเบเบญเบ.
เบเบฒเบเบชเบญเบเบเบฒเบกเบชเบธเบเบเปเบฒเบเบเบตเปเบซเบเปเบฒเบขเปเบฒเบ
WITH RECURSIVE T AS (
-- #1 : ะทะฐะฝะพัะธะผ ะฒ ัะฟะธัะพะบ "ะฟะตัะฒัะต" ะทะฐะฟะธัะธ ะฟะพ ะบะฐะถะดะพะผั ะธะท ะบะปััะตะน ะฝะฐะฑะพัะฐ
WITH wrap AS ( -- "ะผะฐัะตัะธะฐะปะธะทัะตะผ" record'ั, ััะพะฑั ะพะฑัะฐัะตะฝะธะต ะบ ะฟะพะปัะผ ะฝะต ะฒัะทัะฒะฐะปะพ ัะผะฝะพะถะตะฝะธั InitPlan/SubPlan
WITH T AS (
SELECT
(
SELECT
r
FROM
task r
WHERE
owner_id = unnest
ORDER BY
task_date, id
LIMIT 1
) r
FROM
unnest('{1,2,4,8,16,32,64,128,256,512}'::integer[])
)
SELECT
array_agg(r ORDER BY (r).task_date, (r).id) list -- ัะพััะธััะตะผ ัะฟะธัะพะบ ะฒ ะฝัะถะฝะพะผ ะฟะพััะดะบะต
FROM
T
)
SELECT
list
, list[1] rv
, FALSE not_cross
, 0 size
FROM
wrap
UNION ALL
-- #2 : ะฒััะธััะฒะฐะตะผ ะทะฐะฟะธัะธ 1-ะณะพ ะฟะพ ะฟะพััะดะบั ะบะปััะฐ, ะฟะพะบะฐ ะฝะต ะฟะตัะตัะฐะณะฝะตะผ ัะตัะตะท ะทะฐะฟะธัั 2-ะณะพ
SELECT
CASE
-- ะตัะปะธ ะฝะธัะตะณะพ ะฝะต ะฝะฐะนะดะตะฝะพ ะดะปั ะบะปััะฐ 1-ะน ะทะฐะฟะธัะธ
WHEN X._r IS NOT DISTINCT FROM NULL THEN
T.list[2:] -- ัะฑะธัะฐะตะผ ะตะต ะธะท ัะฟะธัะบะฐ
-- ะตัะปะธ ะผั ะะ ะฟะตัะตัะตะบะปะธ ะฟัะธะบะปะฐะดะฝะพะน ะบะปัั 2-ะน ะทะฐะฟะธัะธ
WHEN X.not_cross THEN
T.list -- ะฟัะพััะพ ะฟัะพััะณะธะฒะฐะตะผ ัะพั ะถะต ัะฟะธัะพะบ ะฑะตะท ะผะพะดะธัะธะบะฐัะธะน
-- ะตัะปะธ ะฒ ัะฟะธัะบะต ัะถะต ะฝะตั 2-ะน ะทะฐะฟะธัะธ
WHEN T.list[2] IS NULL THEN
-- ะฟัะพััะพ ะฒะพะทะฒัะฐัะฐะตะผ ะฟัััะพะน ัะฟะธัะพะบ
'{}'
-- ะฟะตัะตัะพััะธัะพะฒัะฒะฐะตะผ ัะปะพะฒะฐัั, ัะฑะธัะฐั 1-ั ะทะฐะฟะธัั ะธ ะดะพะฑะฐะฒะปัั ะฟะพัะปะตะดะฝัั ะธะท ะฝะฐะนะดะตะฝะฝัั
ELSE (
SELECT
coalesce(T.list[2] || array_agg(r ORDER BY (r).task_date, (r).id), '{}')
FROM
unnest(T.list[3:] || X._r) r
)
END
, X._r
, X.not_cross
, T.size + X.not_cross::integer
FROM
T
, LATERAL(
WITH wrap AS ( -- "ะผะฐัะตัะธะฐะปะธะทัะตะผ" record
SELECT
CASE
-- ะตัะปะธ ะฒัะต-ัะฐะบะธ "ะฟะตัะตัะฐะณะฝัะปะธ" ัะตัะตะท 2-ั ะทะฐะฟะธัั
WHEN NOT T.not_cross
-- ัะพ ะฝัะถะฝะฐั ะทะฐะฟะธัั - ะฟะตัะฒะฐั ะธะท ัะฟะฟะธัะบะฐ
THEN T.list[1]
ELSE ( -- ะตัะปะธ ะฝะต ะฟะตัะตัะตะบะปะธ, ัะพ ะบะปัั ะพััะฐะปัั ะบะฐะบ ะฒ ะฟัะตะดัะดััะตะน ะทะฐะฟะธัะธ - ะพััะฐะปะบะธะฒะฐะตะผัั ะพั ะฝะตะต
SELECT
_r
FROM
task _r
WHERE
owner_id = (rv).owner_id AND
(task_date, id) > ((rv).task_date, (rv).id)
ORDER BY
task_date, id
LIMIT 1
)
END _r
)
SELECT
_r
, CASE
-- ะตัะปะธ 2-ะน ะทะฐะฟะธัะธ ัะถะต ะฝะตั ะฒ ัะฟะธัะบะต, ะฝะพ ะผั ั
ะพัั ััะพ-ัะพ ะฝะฐัะปะธ
WHEN list[2] IS NULL AND _r IS DISTINCT FROM NULL THEN
TRUE
ELSE -- ะฝะธัะตะณะพ ะฝะต ะฝะฐัะปะธ ะธะปะธ "ะฟะตัะตัะฐะณะฝัะปะธ"
coalesce(((_r).task_date, (_r).id) < ((list[2]).task_date, (list[2]).id), FALSE)
END not_cross
FROM
wrap
) X
WHERE
T.size < 20 AND -- ะพะณัะฐะฝะธัะธะฒะฐะตะผ ััั ะบะพะปะธัะตััะฒะพ
T.list IS DISTINCT FROM '{}' -- ะธะปะธ ะฟะพะบะฐ ัะฟะธัะพะบ ะฝะต ะบะพะฝัะธะปัั
)
-- #3 : "ัะฐะทะฒะพัะฐัะธะฒะฐะตะผ" ะทะฐะฟะธัะธ - ะฟะพััะดะพะบ ะณะฐัะฐะฝัะธัะพะฒะฐะฝ ะฟะพ ะฟะพัััะพะตะฝะธั
SELECT
(rv).*
FROM
T
WHERE
not_cross; -- ะฑะตัะตะผ ัะพะปัะบะพ "ะฝะตะฟะตัะตัะตะบะฐััะธะต" ะทะฐะฟะธัะธ
เบเบฑเปเบเบเบฑเปเบ, เบเบงเบเปเบฎเบปเบฒ เบเบทเปเบเบฒเบ 50% เบเบญเบเบเปเปเบกเบนเบเบญเปเบฒเบเบชเปเบฒเบฅเบฑเบ 20% เบเบญเบเปเบงเบฅเบฒเบเบฐเบเบดเบเบฑเบ. เบเบฑเปเบเปเบกเปเบ, เบเปเบฒเบเปเบฒเบเบกเบตเปเบซเบเบเบปเบเบเบตเปเบเบฐเปเบเบทเปเบญเบงเปเบฒเบเบฒเบเบญเปเบฒเบเบญเบฒเบเบเบฐเปเบเปเปเบงเบฅเบฒเบเบปเบ (เบเบปเบงเบขเปเบฒเบ, เบเปเปเบกเบนเบเบกเบฑเบเบเบฐเบเปเปเบขเบนเปเปเบเปเบเบ, เปเบฅเบฐเบเปเบฒเบเบเปเบญเบเปเบเบซเบฒเปเบเปเบเบชเปเบฒเบฅเบฑเบเบกเบฑเบ), เบซเบผเบฑเบเบเบฒเบเบเบฑเปเบเบเปเบงเบเบงเบดเบเบตเบเบตเป, เบเปเบฒเบเบชเบฒเบกเบฒเบเบเบถเปเบเบเบฑเบเบเบฒเบเบญเปเบฒเบเบซเบเปเบญเบเบฅเบปเบ. .
เปเบเบเปเบฅเบฐเบเบตเปเบเบเปเปเบเบฒเบก, เปเบงเบฅเบฒเบเบฐเบเบดเบเบฑเบเปเบเปเบเบตเบเบงเปเบฒเปเบเบเบฒเบเปเบฅเบทเบญเบเบเปเบฒเบญเบดเบ "เปเบเป". เปเบเปเบงเปเบฒเปเบ 3 เบเบฒเบเปเบฅเบทเบญเบเบเบตเปเบเบฐเปเบเปเบญเบฑเบเปเบเปเบกเปเบเบเบถเปเบเบเบฑเบเบเปเบฒเบ.
เปเบซเบผเปเบเบเปเปเบกเบนเบ: www.habr.com