SQL HowTo: แžŸแžšแžŸแŸแžš while-loop แžŠแŸ„แž™แž•แŸ’แž‘แžถแž›แŸ‹แž“แŸ…แž€แŸ’แž“แžปแž„แžŸแŸ†แžŽแžฝแžš แžฌ "Elementary three-way"

แž˜แŸ’แžแž„แž˜แŸ’แž€แžถแž› แž—แžถแžšแž€แžทแž…แŸ’แž…แžŸแŸ’แžœแŸ‚แž„แžšแž€แž‘แžทแž“แŸ’แž“แž“แŸแž™แžŠแŸ‚แž›แž–แžถแž€แŸ‹แž–แŸแž“แŸ’แž’แžŠแŸ„แž™แžŸแŸ†แžŽแžปแŸ†แžŸแŸ„แž€แžพแžแžกแžพแž„ แžšแž แžผแžแžŠแž›แŸ‹แž™แžพแž„แž‘แž‘แžฝแž›แž”แžถแž“แž…แŸ†แž“แžฝแž“แž€แŸ†แžŽแžแŸ‹แžแŸ’แžšแžถแžŸแžšแžปแž”แžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž€แžถแžš.

แžงแž‘แžถแž แžšแžŽแŸ "แž‡แžธแžœแžทแž" แž”แŸ†แž•แžปแžแž‚แžบแž”แž„แŸ’แž แžถแž‰ 20 แž”แž‰แŸ’แž แžถแž…แŸ†แžŽแžถแžŸแŸ‹แž‡แžถแž„แž‚แŸ, แžšแžถแž™ แž“แŸ…แž€แŸ’แž“แžปแž„แž”แž‰แŸ’แž‡แžธแž”แžปแž‚แŸ’แž‚แž›แžทแž€ (แžงแž‘แžถแž แžšแžŽแŸแž“แŸ…แž€แŸ’แž“แžปแž„แž“แžถแž™แž€แžŠแŸ’แž‹แžถแž“แžแŸ‚แž˜แžฝแž™) แŸ” แžŸแž˜แŸ’แžšแžถแž”แŸ‹ "แž•แŸ’แž‘แžถแŸ†แž„แž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแž„" แž‡แžถแž…แŸ’แžšแžพแž“แžŠแŸ‚แž›แž˜แžถแž“แž€แžถแžšแžŸแž„แŸ’แžแŸแž”แžแŸ’แž›แžธแŸ—แž“แŸƒแž•แŸ’แž“แŸ‚แž€แž“แŸƒแž€แžถแžšแž„แžถแžš แž”แŸ’แžšแž’แžถแž“แž”แž‘แžŸแŸ’แžšแžŠแŸ€แž„แž‚แŸ’แž“แžถแž‚แžบแžแŸ’แžšแžผแžœแž”แžถแž“แž‘แžถแž˜แž‘แžถแžšแž‡แžถแž‰แžนแž€แž‰แžถแž”แŸ‹แŸ”

SQL HowTo: แžŸแžšแžŸแŸแžš while-loop แžŠแŸ„แž™แž•แŸ’แž‘แžถแž›แŸ‹แž“แŸ…แž€แŸ’แž“แžปแž„แžŸแŸ†แžŽแžฝแžš แžฌ "Elementary three-way"

แž“แŸ…แž€แŸ’แž“แžปแž„แžขแžแŸ’แžแž”แž‘ แž™แžพแž„แž“แžนแž„แž–แžทแž…แžถแžšแžŽแžถแž›แžพแž€แžถแžšแžขแž“แžปแžœแžแŸ’แžแž›แžพ PostgreSQL แž“แŸƒแž€แŸ†แžŽแŸ‚ "แž†แŸ„แžแž›แŸ’แž„แž„แŸ‹" แž“แŸƒแž€แžถแžšแžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™แž”แž‰แŸ’แž แžถแž”แŸ‚แž”แž“แŸแŸ‡ แž€แŸ’แž”แžฝแž“แžŠแŸ„แŸ‡แžŸแŸ’แžšแžถแž™ "แž†แŸ’แž›แžถแžแž‡แžถแž„" แž“แžทแž„แžŸแŸ’แž˜แžปแž‚แžŸแŸ’แž˜แžถแž‰แž”แŸ†แž•แžปแžแŸ” "แžšแž„แŸ’แžœแžทแž›แž‡แžปแŸ†" แž“แŸ…แž€แŸ’แž“แžปแž„ SQL แž‡แžถแž˜แžฝแž™แž“แžนแž„แž›แž€แŸ’แžแžแžŽแŸ’แžŒแž…แžถแž€แž…แŸแž‰แž–แžธแž‘แžทแž“แŸ’แž“แž“แŸแž™แžŠแŸ‚แž›แž”แžถแž“แžšแž€แžƒแžพแž‰แžŠแŸ‚แž›แžขแžถแž…แž˜แžถแž“แž”แŸ’แžšแž™แŸ„แž‡แž“แŸแž‘แžถแŸ†แž„แž€แžถแžšแžขแž—แžทแžœแžŒแŸ’แžแž“แŸแž‘แžผแž‘แŸ… แž“แžทแž„แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž”แŸ’แžšแžพแž”แŸ’แžšแžถแžŸแŸ‹แž€แŸ’แž“แžปแž„แž€แžšแžŽแžธแžŸแŸ’แžšแžŠแŸ€แž„แž‚แŸ’แž“แžถแž•แŸ’แžŸแŸแž„แž‘แŸ€แžแŸ”

แžแŸ„แŸ‡แž™แž€แžŸแŸ†แžŽแžปแŸ†แž‘แžทแž“แŸ’แž“แž“แŸแž™แžŸแžถแž€แž›แŸ’แž”แž„แž–แžธ แžขแžแŸ’แžแž”แž‘แž˜แžปแž“. แžŠแžผแž…แŸ’แž“แŸแŸ‡แžแžถแž€แŸ†แžŽแžแŸ‹แžแŸ’แžšแžถแž›แž‘แŸ’แž’แž•แž›แž˜แžทแž“ "แž›แŸ„แž" แž–แžธแž–แŸแž›แž˜แžฝแž™แž‘แŸ…แž–แŸแž›แž˜แžฝแž™แž“แŸ…แž–แŸแž›แžŠแŸ‚แž›แžแž˜แŸ’แž›แŸƒแžŠแŸ‚แž›แž”แžถแž“แžแž˜แŸ’แžšแŸ€แž”แžแŸ’แžšแžผแžœแž‚แŸ’แž“แžถแŸ” แž–แž„แŸ’แžšแžธแž€แžŸแž“แŸ’แž‘แžŸแŸ’แžŸแž“แŸแž”แŸ’แžšแž’แžถแž“แž”แž‘แžŠแŸ„แž™แž”แž“แŸ’แžแŸ‚แž˜แžŸแŸ„แž…แž˜แŸ’แž”แž„. แž‘แž“แŸ’แž‘แžนแž˜แž“แžนแž„แž“แŸแŸ‡ แžœแžถแž“แžนแž„แž•แŸ’แžแž›แŸ‹แžฑแŸ’แž™แžœแžถแž“แžผแžœแž—แžถแž–แž”แŸ’แž›แŸ‚แž€แž—แŸ’แž›แžถแž˜แŸ— แž แžพแž™แž’แžถแž“แžถแžฑแŸ’แž™แž™แžพแž„แž“แžผแžœแž—แžถแž–แž”แŸ’แž›แŸ‚แž€แž“แŸƒแž›แŸ†แžŠแžถแž”แŸ‹แžแž˜แŸ’แžšแŸ€แž”แŸ–

CREATE INDEX ON task(owner_id, task_date, id);
-- ะฐ ัั‚ะฐั€ั‹ะน - ัƒะดะฐะปะธะผ
DROP INDEX task_owner_id_task_date_idx;

แžŠแžผแž…โ€‹แž‚แŸโ€‹แž”แžถแž“โ€‹แžฎโ€‹แžŠแžผแž…แŸ’แž“แŸแŸ‡โ€‹แž แžพแž™ แž‘แžพแž”โ€‹แž‚แŸโ€‹แžŸแžšแžŸแŸแžš

แž‡แžถแžŠแŸ†แž”แžผแž„ แž…แžผแžšแž™แžพแž„แž‚แžผแžšแž…แŸแž‰แž“แžผแžœแž€แŸ†แžŽแŸ‚แžŸแžถแž˜แž‰แŸ’แž‰แž”แŸ†แž•แžปแžแž“แŸƒแžŸแŸ†แžŽแžพ แžŠแŸ„แž™แž†แŸ’แž›แž„แž€แžถแžแŸ‹แž›แŸแžแžŸแž˜แŸ’แž‚แžถแž›แŸ‹แžšแž”แžŸแŸ‹แžขแŸ’แž“แž€แžŸแŸ†แžŠแŸ‚แž„ แžขแžถแžšแŸแž‡แžถแž’แžถแžแžปแž”แž‰แŸ’แž…แžผแž›:

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;

SQL HowTo: แžŸแžšแžŸแŸแžš while-loop แžŠแŸ„แž™แž•แŸ’แž‘แžถแž›แŸ‹แž“แŸ…แž€แŸ’แž“แžปแž„แžŸแŸ†แžŽแžฝแžš แžฌ "Elementary three-way"
[แžŸแžผแž˜แž˜แžพแž›แž–แž“แŸ’แž™แž›แŸ‹.tensor.ru]

แžŸแŸ„แž€แžŸแŸ…แž”แž“แŸ’แžแžทแž… - แž™แžพแž„แž”แžถแž“แž”แž‰แŸ’แž‡แžถแž‘แžทแž‰แžแŸ‚ 20 แž€แŸ†แžŽแžแŸ‹แžแŸ’แžšแžถแž”แŸ‰แžปแžŽแŸ’แžŽแŸ„แŸ‡ แž แžพแž™ Index Scan แž”แžถแž“แž”แŸ’แžšแž‚แž›แŸ‹แž˜แž€แž™แžพแž„แžœแžทแž‰แŸ” 960 แž‡แžฝแžšแžŠแŸ‚แž›แž”แž“แŸ’แž‘แžถแž”แŸ‹แž˜แž€แž€แŸแžแŸ’แžšแžผแžœแžแž˜แŸ’แžšแŸ€แž” ... แž แžพแž™แžŸแžผแž˜แž–แŸ’แž™แžถแž™แžถแž˜แžขแžถแž“แžแžทแž…แŸ”

unnest + ARRAY

แž€แžถแžšแž–แžทแž…แžถแžšแžŽแžถแžŠแŸ†แž”แžผแž„แžŠแŸ‚แž›แž“แžนแž„แž‡แžฝแž™แž™แžพแž„ - แž”แŸ’แžšแžŸแžทแž“แž”แžพแž™แžพแž„แžแŸ’แžšแžผแžœแž€แžถแžš แžŸแžšแžปแž” 20 แžแž˜แŸ’แžšแŸ€แž” แž€แŸ†แžŽแžแŸ‹แžแŸ’แžšแžถ, แžœแžถแž‚แŸ’แžšแž”แŸ‹แž‚แŸ’แžšแžถแž“แŸ‹แž€แŸ’แž“แžปแž„แž€แžถแžšแžขแžถแž“ แž˜แžทแž“แž›แžพแžŸแž–แžธ 20 แžแž˜แŸ’แžšแŸ€แž”แžแžถแž˜แž›แŸ†แžŠแžถแž”แŸ‹แžŠแžผแž…แž‚แŸ’แž“แžถแžŸแž˜แŸ’แžšแžถแž”แŸ‹แž“แžธแž˜แžฝแž™แŸ— แž‚แž“แŸ’แž›แžนแŸ‡แŸ” แž›แŸ’แžข แžŸแž“แŸ’แž‘แžŸแŸ’แžŸแž“แŸแžŸแž˜แžšแž˜แŸ’แž™ (owner_id, task_date, id) แž™แžพแž„แž˜แžถแž“แŸ”

แž…แžผแžšแž”แŸ’แžšแžพแž™แž“แŸ’แžแž€แžถแžšแžŠแžผแž…แž‚แŸ’แž“แžถแž“แŸƒแž€แžถแžšแžŸแŸ’แžšแž„แŸ‹แž…แŸแž‰แž“แžทแž„ "แž”แŸ’แžšแŸ‚แž‘แŸ…แž‡แžถแž‡แžฝแžšแžˆแžš" แž’แžถแžแžปแžแžถแžšแžถแž„แžขแžถแŸ†แž„แžแŸแž€แŸ’แžšแžถแž›แŸ”, แžŠแžผแž…โ€‹แž‡แžถโ€‹แž“แŸ…โ€‹แž€แŸ’แž“แžปแž„ แžขแžแŸ’แžแž”แž‘แž…แžปแž„แž€แŸ’แžšแŸ„แž™. แž แžพแž™แž€แŸแžขแž“แžปแžœแžแŸ’แž convolution แž‘แŸ… array แžŠแŸ„แž™แž”แŸ’แžšแžพ function 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; -- ... ะธ ั‚ัƒั‚ - ั‚ะพะถะต

SQL HowTo: แžŸแžšแžŸแŸแžš while-loop แžŠแŸ„แž™แž•แŸ’แž‘แžถแž›แŸ‹แž“แŸ…แž€แŸ’แž“แžปแž„แžŸแŸ†แžŽแžฝแžš แžฌ "Elementary three-way"
[แžŸแžผแž˜แž˜แžพแž›แž–แž“แŸ’แž™แž›แŸ‹.tensor.ru]

แžขแžผ แžœแžถโ€‹แž›แŸ’แžขโ€‹แž‡แžถแž„โ€‹แž˜แžปแž“โ€‹แž แžพแž™! แž›แžฟแž“แž‡แžถแž„ 40% แž“แžทแž„แž‘แžทแž“แŸ’แž“แž“แŸแž™แžแžทแž…แž‡แžถแž„ 4.5 แžŠแž„ แžแŸ’แžšแžผแžœแžแŸ‚แžขแžถแž“แŸ”

แž€แžถแžšแž”แž„แŸ’แž€แžพแžแž€แŸ†แžŽแžแŸ‹แžแŸ’แžšแžถแžแžถแžšแžถแž„แžแžถแž˜แžšแž™แŸˆ CTEแžแŸ’แž‰แžปแŸ†แž“แžนแž„แž€แžแŸ‹แž…แŸ†แžŽแžถแŸ† แž€แžšแžŽแžธโ€‹แžแŸ’แž›แŸ‡ แž€แžถแžšแž”แŸ‰แžปแž“แž”แŸ‰แž„แžŠแžพแž˜แŸ’แž”แžธแž’แŸ’แžœแžพแž€แžถแžšแž—แŸ’แž›แžถแž˜แŸ—แž‡แžถแž˜แžฝแž™แž“แžนแž„แžœแžถแž›แž€แŸ†แžŽแžแŸ‹แžแŸ’แžšแžถแž”แž“แŸ’แž‘แžถแž”แŸ‹แž–แžธแžŸแŸ’แžœแŸ‚แž„แžšแž€แžœแžถแž“แŸ…แž€แŸ’แž“แžปแž„แžŸแŸ†แžŽแžฝแžšแžšแž„ แžŠแŸ„แž™แž‚แŸ’แž˜แžถแž“ "แž€แžถแžšแžšแžปแŸ†" แž“แŸ…แž€แŸ’แž“แžปแž„ 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 แžŠแŸ‚แž›แž‡แžถแž–แŸ’แžšแŸ†แžŠแŸ‚แž“แžŠแŸ„แž™แž‚แŸ’แž˜แžถแž“แž›แž€แŸ’แžแžแžŽแŸ’แžŒแžŸแž˜แŸ’แžšแžถแž”แŸ‹แž€แž˜แŸ’แž˜แžœแžทแž’แžธแž”แž„แŸ’แž€แžพแž“แž”แŸ’แžšแžŸแžทแž‘แŸ’แž’แž—แžถแž–แž“แŸ…แž€แŸ’แž“แžปแž„แž€แŸ†แžŽแŸ‚แž‘แžถแŸ†แž„แž“แŸแŸ‡แŸ”

แžงแž”แž€แžšแžŽแŸแž•แŸ’แž‘แžปแž€แžกแžพแž„แžœแžทแž‰

แž“แŸ…แž€แŸ’แž“แžปแž„แž€แŸ†แžŽแŸ‚แž˜แžปแž“แž™แžพแž„แžขแžถแž“แžŸแžšแžปแž” 200 แž‡แžฝแžš แžŸแž˜แŸ’แžšแžถแž”แŸ‹แž‡แžถแž”แŸ’แžšแž™แŸ„แž‡แž“แŸแž“แŸƒแž€แžถแžšแž…แžถแŸ†แž”แžถแž…แŸ‹ 20. แžšแžฝแž…แž‘แŸ…แž แžพแž™แž˜แžทแž“แž˜แŸ‚แž“ 960, แž”แŸ‰แžปแž“แŸ’แžแŸ‚แžŸแžผแž˜แŸ’แž”แžธแžแŸ‚แžแžทแž…แž‡แžถแž„ - แžแžพแžœแžถแžขแžถแž…แž‘แŸ…แžšแžฝแž…แž‘แŸ?

แž…แžผแžšแž™แžพแž„แž–แŸ’แž™แžถแž™แžถแž˜แž”แŸ’แžšแžพแž…แŸ†แžŽแŸแŸ‡แžŠแžนแž„แžŠแŸ‚แž›แž™แžพแž„แžแŸ’แžšแžผแžœแž€แžถแžš แžŸแžšแžปแž” แŸฆแŸ  แž€แŸ†แžŽแžแŸ‹แžแŸ’แžšแžถแŸ” แž“แŸ„แŸ‡โ€‹แž‚แžบโ€‹แž™แžพแž„โ€‹แž“แžนแž„โ€‹แž’แŸ’แžœแžพโ€‹แž€แžถแžšโ€‹แžŠแž€โ€‹แž‘แžทแž“แŸ’แž“แž“แŸแž™โ€‹แžŠแžŠแŸ‚แž›แŸ—โ€‹แžšแž แžผแžโ€‹แžŠแž›แŸ‹โ€‹แž…แŸ†แž“แžฝแž“โ€‹แžŠแŸ‚แž›โ€‹แž™แžพแž„โ€‹แžแŸ’แžšแžผแžœโ€‹แž€แžถแžšโ€‹แžแŸ’แžšแžผแžœโ€‹แž”แžถแž“โ€‹แžŠแž›แŸ‹แŸ”

แž‡แŸ†แž แžถแž“แž‘แžธ 1: แž…แžถแž”แŸ‹แž•แŸ’แžแžพแž˜แž”แž‰แŸ’แž‡แžธ

แž‡แžถแž€แŸ‹แžŸแŸ’แžแŸ‚แž„ แž”แž‰แŸ’แž‡แžธ "แž‚แŸ„แž›แžŠแŸ…" แž“แŸƒแž’แžถแžแžปแž…แŸ†แž“แžฝแž“ 20 แžšแž”แžŸแŸ‹แž™แžพแž„แž‚แžฝแžšแžแŸ‚แž…แžถแž”แŸ‹แž•แŸ’แžแžพแž˜แžŠแŸ„แž™แž’แžถแžแžป "แžŠแŸ†แž”แžผแž„" แžŸแž˜แŸ’แžšแžถแž”แŸ‹แžŸแŸ„แž˜แŸ’แž…แžถแžŸแŸ‹_id แžšแž”แžŸแŸ‹แž™แžพแž„แŸ” แžŠแžผแž…แŸ’แž“แŸแŸ‡แžŠแŸ†แž”แžผแž„แž™แžพแž„แžšแž€แžƒแžพแž‰แž”แŸ‚แž”แž“แŸแŸ‡ "แžŠแŸ†แž”แžผแž„แž”แŸ†แž•แžปแž" แžŸแž˜แŸ’แžšแžถแž”แŸ‹แžŸแŸ„แž“แžธแž˜แžฝแž™แŸ— แž แžพแž™แžŠแžถแž€แŸ‹แžœแžถแž“แŸ…แž€แŸ’แž“แžปแž„แž”แž‰แŸ’แž‡แžธแžŠแŸ„แž™แžแž˜แŸ’แžšแŸ€แž”แžœแžถแžแžถแž˜แž›แŸ†แžŠแžถแž”แŸ‹แžŠแŸ‚แž›แž™แžพแž„แž…แž„แŸ‹แž”แžถแž“ - (task_date, id)แŸ”

SQL HowTo: แžŸแžšแžŸแŸแžš while-loop แžŠแŸ„แž™แž•แŸ’แž‘แžถแž›แŸ‹แž“แŸ…แž€แŸ’แž“แžปแž„แžŸแŸ†แžŽแžฝแžš แžฌ "Elementary three-way"

แž‡แŸ†แž แžถแž“แž‘แžธ 2: แžŸแŸ’แžœแŸ‚แž„แžšแž€แž€แŸ†แžŽแžแŸ‹แžแŸ’แžšแžถ "แž”แž“แŸ’แž‘แžถแž”แŸ‹"

แžฅแžกแžผแžœแž“แŸแŸ‡แž”แŸ’แžšแžŸแžทแž“แž”แžพแž™แžพแž„แž™แž€แž’แžถแžแžปแžŠแŸ†แž”แžผแž„แž–แžธแž”แž‰แŸ’แž‡แžธแžšแž”แžŸแŸ‹แž™แžพแž„แž แžพแž™แž…แžถแž”แŸ‹แž•แŸ’แžแžพแž˜ "แž‡แŸ†แž แžถแž“" แž”แž“แŸ’แžแŸ‚แž˜แž‘แŸ€แžแž…แžปแŸ‡แž€แŸ’แžšแŸ„แž˜แžŸแž“แŸ’แž‘แžŸแŸ’แžŸแž“แŸ แž‡แžถแž˜แžฝแž™แž“แžนแž„แž€แžถแžšแžšแž€แŸ’แžŸแžถแž‘แžปแž€ owner_id-key แž”แž“แŸ’แž‘แžถแž”แŸ‹แž˜แž€แž€แŸ†แžŽแžแŸ‹แžแŸ’แžšแžถแžŠแŸ‚แž›แž”แžถแž“แžšแž€แžƒแžพแž‰แž‘แžถแŸ†แž„แžขแžŸแŸ‹แž‚แžบแž‚แŸ’แžšแžถแž“แŸ‹แžแŸ‚แž‡แžถแž›แŸแžแž”แž“แŸ’แž‘แžถแž”แŸ‹แž“แŸ…แž€แŸ’แž“แžปแž„แž€แžถแžšแž‡แŸ’แžšแžพแžŸแžšแžพแžŸแž›แž‘แŸ’แž’แž•แž›แž”แŸ‰แžปแžŽแŸ’แžŽแŸ„แŸ‡แŸ” แž‡แžถแž€แžถแžšแž–แžทแžแžŽแžถแžŸแŸ‹แž˜แžถแž“แžแŸ‚ แžšแž แžผแžแžŠแž›แŸ‹แž™แžพแž„แž†แŸ’แž›แž„แž€แžถแžแŸ‹แžŸแŸ„แžŠแŸ‚แž›แž”แžถแž“แžขแž“แžปแžœแžแŸ’แž แž’แžถแžแžปแž‘แžธแž–แžธแžšแž“แŸ…แž€แŸ’แž“แžปแž„แž”แž‰แŸ’แž‡แžธแŸ”

แž”แŸ’แžšแžŸแžทแž“แž”แžพแžœแžถแž”แŸ’แžšแŸ‚แžแžถแž™แžพแž„ "แž†แŸ’แž›แž„แž€แžถแžแŸ‹" แž’แžถแžแžปแž‘แžธแž–แžธแžšแž”แž“แŸ’แž‘แžถแž”แŸ‹แž˜แž€ แž’แžถแžแžปแžŠแŸ‚แž›แž”แžถแž“แžขแžถแž“แž…แžปแž„แž€แŸ’แžšแŸ„แž™แž‚แžฝแžšแžแŸ‚แžแŸ’แžšแžผแžœแž”แžถแž“แž”แž“แŸ’แžแŸ‚แž˜แž‘แŸ…แž€แŸ’แž“แžปแž„แž”แž‰แŸ’แž‡แžธแž‡แŸ†แž“แžฝแžŸแžฑแŸ’แž™แž›แŸแžแž‘แžธแž˜แžฝแž™ (แž‡แžถแž˜แžฝแž™ owner_id แžŠแžผแž…แž‚แŸ’แž“แžถ) แž”แž“แŸ’แž‘แžถแž”แŸ‹แž–แžธแž“แŸ„แŸ‡แž”แž‰แŸ’แž‡แžธแžแŸ’แžšแžผแžœแž”แžถแž“แžแž˜แŸ’แžšแŸ€แž”แž˜แŸ’แžแž„แž‘แŸ€แžแŸ”

SQL HowTo: แžŸแžšแžŸแŸแžš while-loop แžŠแŸ„แž™แž•แŸ’แž‘แžถแž›แŸ‹แž“แŸ…แž€แŸ’แž“แžปแž„แžŸแŸ†แžŽแžฝแžš แžฌ "Elementary three-way"

แž“แŸ„แŸ‡แž‚แžบแž™แžพแž„แžแŸ‚แž„แžแŸ‚แž‘แž‘แžฝแž›แž”แžถแž“แžแžถแž”แž‰แŸ’แž‡แžธแž˜แžทแž“แž˜แžถแž“แž’แžถแžแžปแž›แžพแžŸแž–แžธแž˜แžฝแž™แžŸแž˜แŸ’แžšแžถแž”แŸ‹แžŸแŸ„แž“แžธแž˜แžฝแž™แŸ—แž‘แŸ (แž”แŸ’แžšแžŸแžทแž“แž”แžพแž’แžถแžแžปแžแŸ’แžšแžผแžœแž”แžถแž“แž”แž‰แŸ’แž…แž”แŸ‹แž แžพแž™แž™แžพแž„แž˜แžทแž“แž”แžถแž“ "แž†แŸ’แž›แž„แž€แžถแžแŸ‹" แž“แŸ„แŸ‡แž’แžถแžแžปแžŠแŸ†แž”แžผแž„แž“แžนแž„แž”แžถแžแŸ‹แž–แžธแž”แž‰แŸ’แž‡แžธแž แžพแž™แž‚แŸ’แž˜แžถแž“แžขแŸ’แžœแžธแž“แžนแž„แžแŸ’แžšแžผแžœแž”แžถแž“แž”แž“แŸ’แžแŸ‚แž˜แž‘แŸแŸ” ), แž แžพแž™โ€‹แž–แžฝแž€โ€‹แž‚แŸ แžแŸ‚แž„แžแŸ‚แžแž˜แŸ’แžšแŸ€แž” แž“แŸ…แž€แŸ’แž“แžปแž„แž›แŸ†แžŠแžถแž”แŸ‹แžกแžพแž„แž“แŸƒแž€แžผแž“แžŸแŸ„แž€แž˜แŸ’แž˜แžœแžทแž’แžธ (task_date, id) แŸ”

SQL HowTo: แžŸแžšแžŸแŸแžš while-loop แžŠแŸ„แž™แž•แŸ’แž‘แžถแž›แŸ‹แž“แŸ…แž€แŸ’แž“แžปแž„แžŸแŸ†แžŽแžฝแžš แžฌ "Elementary three-way"

แž‡แŸ†แž แžถแž“แž‘แžธ 3แŸ– แžแŸ’แžšแž„ แž“แžทแž„แž–แž„แŸ’แžšแžธแž€แž€แŸ†แžŽแžแŸ‹แžแŸ’แžšแžถ

แž“แŸ…แž€แŸ’แž“แžปแž„แž•แŸ’แž“แŸ‚แž€แž“แŸƒแž‡แžฝแžšแžŠแŸแž€แž“แŸƒแž€แžถแžšแž‡แŸ’แžšแžพแžŸแžšแžพแžŸแžกแžพแž„แžœแžทแž‰แžšแž”แžŸแŸ‹แž™แžพแž„ แž€แŸ†แžŽแžแŸ‹แžแŸ’แžšแžถแž˜แžฝแž™แž…แŸ†แž“แžฝแž“ 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; -- ะฑะตั€ะตะผ ั‚ะพะปัŒะบะพ "ะฝะตะฟะตั€ะตัะตะบะฐัŽั‰ะธะต" ะทะฐะฟะธัะธ

SQL HowTo: แžŸแžšแžŸแŸแžš while-loop แžŠแŸ„แž™แž•แŸ’แž‘แžถแž›แŸ‹แž“แŸ…แž€แŸ’แž“แžปแž„แžŸแŸ†แžŽแžฝแžš แžฌ "Elementary three-way"
[แžŸแžผแž˜แž˜แžพแž›แž–แž“แŸ’แž™แž›แŸ‹.tensor.ru]

แžŠแžผแž…แŸ’แž“แŸแŸ‡แž™แžพแž„ แž€แžถแžšแž‡แžฝแž‰แžŠแžผแžšแž‘แžทแž“แŸ’แž“แž“แŸแž™ 50% แžขแžถแž“แžŸแž˜แŸ’แžšแžถแž”แŸ‹แžšแž™แŸˆแž–แŸแž›แž”แŸ’แžšแžแžทแž”แžแŸ’แžแžท 20%. แž“แŸ„แŸ‡แž‚แžบแž”แŸ’แžšแžŸแžทแž“แž”แžพแžขแŸ’แž“แž€แž˜แžถแž“แž แŸแžแžปแž•แž›แžŠแžพแž˜แŸ’แž”แžธแž‡แžฟแžแžถแž€แžถแžšแžขแžถแž“แžขแžถแž…แž˜แžถแž“แžšแž™แŸˆแž–แŸแž›แž™แžผแžš (แžงแž‘แžถแž แžšแžŽแŸ แž‘แžทแž“แŸ’แž“แž“แŸแž™แž…แŸ’แžšแžพแž“แžแŸ‚แž˜แžทแž“แž“แŸ…แž€แŸ’แž“แžปแž„แžƒแŸ’แž›แžถแŸ†แž„แžŸแž˜แŸ’แž„แžถแžแŸ‹ แž แžพแž™แžขแŸ’แž“แž€แžแŸ’แžšแžผแžœแž…แžผแž›แž‘แŸ…แž€แžถแž“แŸ‹แžแžถแžŸแžŸแž˜แŸ’แžšแžถแž”แŸ‹แžœแžถ) แž”แž“แŸ’แž‘แžถแž”แŸ‹แž˜แž€แžแžถแž˜แžšแž”แŸ€แž”แž“แŸแŸ‡แžขแŸ’แž“แž€แžขแžถแž…แž–แžนแž„แž•แŸ’แžขแŸ‚แž€แž›แžพแž€แžถแžšแžขแžถแž“แžแžทแž…แŸ”

แž€แŸ’แž“แžปแž„แž€แžšแžŽแžธแžŽแžถแž€แŸแžŠแŸ„แž™แž–แŸแž›แžœแŸแž›แžถแž”แŸ’แžšแžแžทแž”แžแŸ’แžแžทแž”แžถแž“แž”แŸ’แžšแŸ‚แž‘แŸ…แž‡แžถแž”แŸ’แžšแžŸแžพแžšแž‡แžถแž„แž“แŸ…แž€แŸ’แž“แžปแž„แž‡แž˜แŸ’แžšแžพแžŸแžŠแŸ†แž”แžผแž„ "แž†แŸ„แžแž›แŸ’แž„แž„แŸ‹" แŸ” แž”แŸ‰แžปแž“แŸ’แžแŸ‚แžแžพแž‡แž˜แŸ’แžšแžพแžŸ 3 แžŽแžถแžŠแŸ‚แž›แžแŸ’แžšแžผแžœแž”แŸ’แžšแžพแž‚แžบแžขแžถแžŸแŸ’แžšแŸแž™แž›แžพแžขแŸ’แž“แž€แŸ”

แž”แŸ’แžšแž—แž–: www.habr.com

แž”แž“แŸ’แžแŸ‚แž˜แž˜แžแžทแž™แŸ„แž”แž›แŸ‹