Skip to main content
added 227 characters in body
Source Link
Zegarek
  • 29.9k
  • 5
  • 27
  • 32

Cycle detection is a built-in feature of recursive CTEs: demo at db<>fiddle

  1. CYCLE clausesclause informs it which value indicates a loop if it repeats
  2. It's followed by a boolean field that it'll populate, populated for the records with loops and, then an array field that holds the whole path/group with the cycle.
  3. Since the third field path accumulates all keys, it can grow quickly on larger and more complex sets. As an optimised, fast and memory-efficient alternative, consider pgrouting.
WITH recursive tmp AS ( SELECT supervisor_id, emp_id FROM incoming_records UNION ALL SELECT tmp.supervisor_id, t.emp_id FROM tmp INNER JOIN incoming_records AS t ON t.supervisor_id = tmp.emp_id )CYCLE emp_id SET is_cycle USING path ----- here SELECT * FROM tmp WHERE is_cycle; 
supervisor_id emp_id is_cycle path
rt14 rt14 t {(rt14),(rt14)}
rt15 rt16 t {(rt16),(rt15),(rt16)}
rt16 rt15 t {(rt15),(rt16),(rt15)}
rt17 rt18 t {(rt18),(rt19),(rt17),(rt18)}
rt18 rt19 t {(rt19),(rt17),(rt18),(rt19)}
rt19 rt17 t {(rt17),(rt18),(rt19),(rt17)}
rt20 rt21 t {(rt21),(rt22),(rt23),(rt20),(rt21)}
rt21 rt22 t {(rt22),(rt23),(rt20),(rt21),(rt22)}
rt22 rt23 t {(rt23),(rt20),(rt21),(rt22),(rt23)}
rt23 rt20 t {(rt20),(rt21),(rt22),(rt23),(rt20)}

If you want to avoid them rather than select only those, switch to WHERE NOT is_cycle;.

The SQL-standard CYCLE clause for built-in cycle detection was added in v14.

Cycle detection is a built-in feature of recursive CTEs: demo at db<>fiddle

  1. CYCLE clauses informs it which value indicates a loop if it repeats
  2. It's followed by a boolean field that it'll populate for the records with loops and an array field that holds the whole path/group with the cycle.
WITH recursive tmp AS ( SELECT supervisor_id, emp_id FROM incoming_records UNION ALL SELECT tmp.supervisor_id, t.emp_id FROM tmp INNER JOIN incoming_records AS t ON t.supervisor_id = tmp.emp_id )CYCLE emp_id SET is_cycle USING path ----- here SELECT * FROM tmp WHERE is_cycle; 
supervisor_id emp_id is_cycle path
rt14 rt14 t {(rt14),(rt14)}
rt15 rt16 t {(rt16),(rt15),(rt16)}
rt16 rt15 t {(rt15),(rt16),(rt15)}
rt17 rt18 t {(rt18),(rt19),(rt17),(rt18)}
rt18 rt19 t {(rt19),(rt17),(rt18),(rt19)}
rt19 rt17 t {(rt17),(rt18),(rt19),(rt17)}
rt20 rt21 t {(rt21),(rt22),(rt23),(rt20),(rt21)}
rt21 rt22 t {(rt22),(rt23),(rt20),(rt21),(rt22)}
rt22 rt23 t {(rt23),(rt20),(rt21),(rt22),(rt23)}
rt23 rt20 t {(rt20),(rt21),(rt22),(rt23),(rt20)}

If you want to avoid them rather than select only those, switch to WHERE NOT is_cycle;.

The SQL-standard CYCLE clause for built-in cycle detection was added in v14.

Cycle detection is a built-in feature of recursive CTEs: demo at db<>fiddle

  1. CYCLE clause informs it which value indicates a loop if it repeats
  2. It's followed by a boolean field, populated for the records with loops, then an array field that holds the whole path/group with the cycle.
  3. Since the third field path accumulates all keys, it can grow quickly on larger and more complex sets. As an optimised, fast and memory-efficient alternative, consider pgrouting.
WITH recursive tmp AS ( SELECT supervisor_id, emp_id FROM incoming_records UNION ALL SELECT tmp.supervisor_id, t.emp_id FROM tmp INNER JOIN incoming_records AS t ON t.supervisor_id = tmp.emp_id )CYCLE emp_id SET is_cycle USING path ----- here SELECT * FROM tmp WHERE is_cycle; 
supervisor_id emp_id is_cycle path
rt14 rt14 t {(rt14),(rt14)}
rt15 rt16 t {(rt16),(rt15),(rt16)}
rt16 rt15 t {(rt15),(rt16),(rt15)}
rt17 rt18 t {(rt18),(rt19),(rt17),(rt18)}
rt18 rt19 t {(rt19),(rt17),(rt18),(rt19)}
rt19 rt17 t {(rt17),(rt18),(rt19),(rt17)}
rt20 rt21 t {(rt21),(rt22),(rt23),(rt20),(rt21)}
rt21 rt22 t {(rt22),(rt23),(rt20),(rt21),(rt22)}
rt22 rt23 t {(rt23),(rt20),(rt21),(rt22),(rt23)}
rt23 rt20 t {(rt20),(rt21),(rt22),(rt23),(rt20)}

If you want to avoid them rather than select only those, switch to WHERE NOT is_cycle;.

The SQL-standard CYCLE clause for built-in cycle detection was added in v14.

added 4 characters in body
Source Link
Zegarek
  • 29.9k
  • 5
  • 27
  • 32

Cycle detection is a built-in feature of recursive CTEs: demo at db<>fiddle

  1. CYCLE clauses informs it which value indicates a loop if it repeats
  2. It's followed by a boolean field that it'll populate for the records with loops and an array field that holds the whole path/group with the cycle.
WITH recursive tmp AS ( SELECT supervisor_id, emp_id FROM incoming_records UNION ALL SELECT tmp.supervisor_id, t.emp_id FROM tmp INNER JOIN incoming_records AS t ON t.supervisor_id = tmp.emp_id )CYCLE emp_id SET is_cycle USING path ----- here SELECT * FROM tmp WHERE is_cycle; 
supervisor_id emp_id is_cycle path
rt14 rt14 t {(rt14),(rt14)}
rt15 rt16 t {(rt16),(rt15),(rt16)}
rt16 rt15 t {(rt15),(rt16),(rt15)}
rt17 rt18 t {(rt18),(rt19),(rt17),(rt18)}
rt18 rt19 t {(rt19),(rt17),(rt18),(rt19)}
rt19 rt17 t {(rt17),(rt18),(rt19),(rt17)}
rt20 rt21 t {(rt21),(rt22),(rt23),(rt20),(rt21)}
rt21 rt22 t {(rt22),(rt23),(rt20),(rt21),(rt22)}
rt22 rt23 t {(rt23),(rt20),(rt21),(rt22),(rt23)}
rt23 rt20 t {(rt20),(rt21),(rt22),(rt23),(rt20)}

If you want to avoid them rather than select only those, switch to WHERE NOT is_cycle;.

The SQL-standard CYCLE clause for built-in cycle detection was added in v14.

Cycle detection is a built-in feature of recursive CTEs: demo at db<>fiddle

  1. CYCLE clauses informs it which value indicates a loop if it repeats
  2. It's followed by a boolean field that it'll populate for the records with loops an array field that holds the whole path/group with the cycle.
WITH recursive tmp AS ( SELECT supervisor_id, emp_id FROM incoming_records UNION ALL SELECT tmp.supervisor_id, t.emp_id FROM tmp INNER JOIN incoming_records AS t ON t.supervisor_id = tmp.emp_id )CYCLE emp_id SET is_cycle USING path ----- here SELECT * FROM tmp WHERE is_cycle; 
supervisor_id emp_id is_cycle path
rt14 rt14 t {(rt14),(rt14)}
rt15 rt16 t {(rt16),(rt15),(rt16)}
rt16 rt15 t {(rt15),(rt16),(rt15)}
rt17 rt18 t {(rt18),(rt19),(rt17),(rt18)}
rt18 rt19 t {(rt19),(rt17),(rt18),(rt19)}
rt19 rt17 t {(rt17),(rt18),(rt19),(rt17)}
rt20 rt21 t {(rt21),(rt22),(rt23),(rt20),(rt21)}
rt21 rt22 t {(rt22),(rt23),(rt20),(rt21),(rt22)}
rt22 rt23 t {(rt23),(rt20),(rt21),(rt22),(rt23)}
rt23 rt20 t {(rt20),(rt21),(rt22),(rt23),(rt20)}

If you want to avoid them rather than select only those, switch to WHERE NOT is_cycle;.

The SQL-standard CYCLE clause for built-in cycle detection was added in v14.

Cycle detection is a built-in feature of recursive CTEs: demo at db<>fiddle

  1. CYCLE clauses informs it which value indicates a loop if it repeats
  2. It's followed by a boolean field that it'll populate for the records with loops and an array field that holds the whole path/group with the cycle.
WITH recursive tmp AS ( SELECT supervisor_id, emp_id FROM incoming_records UNION ALL SELECT tmp.supervisor_id, t.emp_id FROM tmp INNER JOIN incoming_records AS t ON t.supervisor_id = tmp.emp_id )CYCLE emp_id SET is_cycle USING path ----- here SELECT * FROM tmp WHERE is_cycle; 
supervisor_id emp_id is_cycle path
rt14 rt14 t {(rt14),(rt14)}
rt15 rt16 t {(rt16),(rt15),(rt16)}
rt16 rt15 t {(rt15),(rt16),(rt15)}
rt17 rt18 t {(rt18),(rt19),(rt17),(rt18)}
rt18 rt19 t {(rt19),(rt17),(rt18),(rt19)}
rt19 rt17 t {(rt17),(rt18),(rt19),(rt17)}
rt20 rt21 t {(rt21),(rt22),(rt23),(rt20),(rt21)}
rt21 rt22 t {(rt22),(rt23),(rt20),(rt21),(rt22)}
rt22 rt23 t {(rt23),(rt20),(rt21),(rt22),(rt23)}
rt23 rt20 t {(rt20),(rt21),(rt22),(rt23),(rt20)}

If you want to avoid them rather than select only those, switch to WHERE NOT is_cycle;.

The SQL-standard CYCLE clause for built-in cycle detection was added in v14.

added 131 characters in body
Source Link
Zegarek
  • 29.9k
  • 5
  • 27
  • 32

Cycle detection is a built-in feature of recursive CTEs: demo at db<>fiddle

  1. CYCLE clauses informs it which value indicates a loop if it repeats
  2. It's followed by a boolean field that it'll populate for the records with loops an array field that holds the whole path/group with the cycle.
WITH recursive tmp AS ( SELECT supervisor_id, emp_id FROM incoming_records UNION ALL SELECT tmp.supervisor_id, t.emp_id FROM tmp INNER JOIN incoming_records AS t ON t.supervisor_id = tmp.emp_id )CYCLE emp_id SET is_cycle USING path ----- here SELECT * FROM tmp WHERE is_cycle; 
supervisor_id emp_id is_cycle path
rt14 rt14 t {(rt14),(rt14)}
rt15 rt16 t {(rt16),(rt15),(rt16)}
rt16 rt15 t {(rt15),(rt16),(rt15)}
rt17 rt18 t {(rt18),(rt19),(rt17),(rt18)}
rt18 rt19 t {(rt19),(rt17),(rt18),(rt19)}
rt19 rt17 t {(rt17),(rt18),(rt19),(rt17)}
rt20 rt21 t {(rt21),(rt22),(rt23),(rt20),(rt21)}
rt21 rt22 t {(rt22),(rt23),(rt20),(rt21),(rt22)}
rt22 rt23 t {(rt23),(rt20),(rt21),(rt22),(rt23)}
rt23 rt20 t {(rt20),(rt21),(rt22),(rt23),(rt20)}

If you want to avoid them rather than select only those, switch to WHERE NOT is_cycle;.

The SQL-standard CYCLE clause for built-in cycle detection was added in v14.

Cycle detection is a built-in feature of recursive CTEs: demo at db<>fiddle

  1. CYCLE clauses informs it which value indicates a loop if it repeats
  2. It's followed by a boolean field that it'll populate for the records with loops an array field that holds the whole path/group with the cycle.
WITH recursive tmp AS ( SELECT supervisor_id, emp_id FROM incoming_records UNION ALL SELECT tmp.supervisor_id, t.emp_id FROM tmp INNER JOIN incoming_records AS t ON t.supervisor_id = tmp.emp_id )CYCLE emp_id SET is_cycle USING path ----- here SELECT * FROM tmp WHERE is_cycle; 
supervisor_id emp_id is_cycle path
rt14 rt14 t {(rt14),(rt14)}
rt15 rt16 t {(rt16),(rt15),(rt16)}
rt16 rt15 t {(rt15),(rt16),(rt15)}
rt17 rt18 t {(rt18),(rt19),(rt17),(rt18)}
rt18 rt19 t {(rt19),(rt17),(rt18),(rt19)}
rt19 rt17 t {(rt17),(rt18),(rt19),(rt17)}
rt20 rt21 t {(rt21),(rt22),(rt23),(rt20),(rt21)}
rt21 rt22 t {(rt22),(rt23),(rt20),(rt21),(rt22)}
rt22 rt23 t {(rt23),(rt20),(rt21),(rt22),(rt23)}
rt23 rt20 t {(rt20),(rt21),(rt22),(rt23),(rt20)}

Cycle detection is a built-in feature of recursive CTEs: demo at db<>fiddle

  1. CYCLE clauses informs it which value indicates a loop if it repeats
  2. It's followed by a boolean field that it'll populate for the records with loops an array field that holds the whole path/group with the cycle.
WITH recursive tmp AS ( SELECT supervisor_id, emp_id FROM incoming_records UNION ALL SELECT tmp.supervisor_id, t.emp_id FROM tmp INNER JOIN incoming_records AS t ON t.supervisor_id = tmp.emp_id )CYCLE emp_id SET is_cycle USING path ----- here SELECT * FROM tmp WHERE is_cycle; 
supervisor_id emp_id is_cycle path
rt14 rt14 t {(rt14),(rt14)}
rt15 rt16 t {(rt16),(rt15),(rt16)}
rt16 rt15 t {(rt15),(rt16),(rt15)}
rt17 rt18 t {(rt18),(rt19),(rt17),(rt18)}
rt18 rt19 t {(rt19),(rt17),(rt18),(rt19)}
rt19 rt17 t {(rt17),(rt18),(rt19),(rt17)}
rt20 rt21 t {(rt21),(rt22),(rt23),(rt20),(rt21)}
rt21 rt22 t {(rt22),(rt23),(rt20),(rt21),(rt22)}
rt22 rt23 t {(rt23),(rt20),(rt21),(rt22),(rt23)}
rt23 rt20 t {(rt20),(rt21),(rt22),(rt23),(rt20)}

If you want to avoid them rather than select only those, switch to WHERE NOT is_cycle;.

The SQL-standard CYCLE clause for built-in cycle detection was added in v14.

Source Link
Zegarek
  • 29.9k
  • 5
  • 27
  • 32
Loading