Skip to content
Advertisement

Is branch pruning possible for recursive cte query

This is inspired by question Retrieve a list of lists in one SQL statement – I have come up with a solution, but I have doubts on its efficiency.

To restate the problem:

  • we have 2 Tables: Person and Parent
  • Person contains basic data about each person
  • Parent is a join table relating person with its parents
  • each Person can have multiple parents
  • we want to receive each person data with list of all their ancestors – each ancestor in its own row
  • if there are no ancestors, we have only one row for that person, with null parentId

Here is the data format:

Person table

Parent table

Person has rows with values PK

Parent has rows with values

So person 1 has ancestors 2, 3, 4

I want the output in the following form

My solution used recursive CTE query, but my fear is that it produces too many rows, as each subtree can be entered multiple times. I needed to filter out duplicates with distinct, and execution plan shows that, even with this simple data, sorting for distinct takes 50% of the time. Here is my query:

http://sqlfiddle.com/#!18/d7d62/4

My questions:

  • can I somehow prune the already visited branches, so that recursive-CTE does not produce duplicate rows, and final distinct is not necessary
  • is recursive CTE a right approach to this problem?

Advertisement

Answer

On PostgreSQL you can acheive that by replacing UNION ALL with UNION. So the query looks like that:

http://sqlfiddle.com/#!17/225cf4/4

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement