HiveBrain v1.2.0
Get Started
← Back to all entries
patternsqlModerate

self-joins in recursive CTE: `recursive reference must not appear more than once`?

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
oncereferencemustthanmorecterecursivenotappearjoins

Problem

This is tested with PostgreSQL 9.6, but it's a general SQL question.

Is it possible to use self-joins of the recursive table in a recursive CTE (rCTE)?

I tried the following rCTE containing a self-join of the recursive term x,

WITH RECURSIVE
x (id) AS (
  SELECT 1 id UNION ALL SELECT x1.id+x2.id FROM x x1, x x2
  WHERE x1.id < 5 AND x2.id < 5 AND x1.id = x2.id
  )
SELECT * FROM x;


, which hopefully should be equivalent to:

WITH RECURSIVE
x (id) AS (
  SELECT 1 id UNION ALL SELECT id+id FROM x WHERE id < 5
  )
SELECT * FROM x;


But the former rCTE generates an error:

ERROR:  recursive reference to query "x" must not appear more than once 
LINE 3:   SELECT 1 id UNION ALL SELECT x1.id+x2.id FROM x x1, x x2


Is there a fundamental reason why the recursive reference must not appear more than once? Or is this just a limitation of the PostgreSQL implementation?

Also, is there a work-around?

Solution

Indeed error like recursive reference to query "x" must not appear more than once is some strange restriction applied in postgres. And I made assumption it is because their parser just simple distinguish recursive and non-recursive part of query by present of that table.
Meantime for that present nice workaround - you may use nested CTE (WITH statement), and give another name for such table. For your initial example it will look like:

`WITH RECURSIVE
x (id) AS (
SELECT 1 id
UNION ALL
SELECT * FROM (
WITH x_inner AS ( -- Workaround of error: recursive reference to query "x" must not appear more than once
SELECT * FROM x
)
SELECT x1.id+x2.id
FROM x_inner x1, x_inner x2
WHERE x1.id

You could try it in SQL fiddle.

Context

StackExchange Database Administrators Q#185140, answer score: 12

Revisions (0)

No revisions yet.