I’m storing a tree in Postgres linked via a parent_id column. I want to find the leaves of the tree, as in, those elements that have no children. Here’s the query I have so far:
where("id NOT IN ( SELECT parent_id FROM elements WHERE parent_id IS NOT NULL )")
Is there a better way to write this query? I was trying to think of a way to handle it with a join, as I’ve heard that’s more efficient, but wasn’t able to come up with anything. Also, is there a way to do this without raw SQL and instead use ActiveRecord?
UPDATE: Here’s the schema:
Column | Type | Modifiers
------------+-----------------------------+--------------------
id | character varying(36) | not null
user_id | character varying(36) | not null
parent_id | character varying(36) |
title | character varying(255) |
created_at | timestamp without time zone | not null
updated_at | timestamp without time zone | not null
Indexes:
"index_elements_on_id" UNIQUE, btree (id)
"index_elements_on_parent_id" btree (parent_id)
"index_elements_on_user_id" btree (user_id)
The technique is called “exclusion join”.