How can I use string_to_array
or split_part
on another column value.
I want do something like select * from tenants where id IN (select string_to_array(select ancestry from tenants where id = 39,'/'));
-[ RECORD 1 ]------------- ----------------------
id | 1
domain |
subdomain |
name | My Company
login_text |
logo_file_name |
logo_content_type |
logo_file_size |
logo_updated_at |
login_logo_file_name |
login_logo_content_type |
login_logo_file_size |
login_logo_updated_at |
ancestry |
divisible | t
description | Tenant for My Company
use_config_for_attributes | t
default_miq_group_id | 1
source_type |
source_id |
-[ RECORD 3 ]------------- ----------------------
id | 35
domain |
subdomain |
name | Tenant_2
login_text |
logo_file_name |
logo_content_type |
logo_file_size |
logo_updated_at |
login_logo_file_name |
login_logo_content_type |
login_logo_file_size |
login_logo_updated_at |
ancestry | 1
divisible | t
description | Tenant_2
use_config_for_attributes | f
default_miq_group_id | 36
source_type |
source_id |
-[ RECORD 7 ]------------- ----------------------
id | 39
domain |
subdomain |
name | Child_Teanant_202
login_text |
logo_file_name |
logo_content_type |
logo_file_size |
logo_updated_at |
login_logo_file_name |
login_logo_content_type |
login_logo_file_size |
login_logo_updated_at |
ancestry | 1/35
divisible | t
description | Child_Teanant_202
use_config_for_attributes | f
default_miq_group_id | 52
source_type |
source_id |
CodePudding user response:
Use regex to enforce word boundaries:
select *
from tenants
where (select ancestry from tenants where id = 39)
~ ('\y' || id || '\y')
See live demo.
Without the word boundaries an id of 1
would match an ancestry of 123
.
Note Postgres's unusual regex for word boundary \y
, which elsewhere is \b
.
CodePudding user response:
There are two ways to solve this.
One is to simply unnest the elements of ancestry
select *
from tenants
where id in (select a.id::int
from tenants t2
cross join unnest(string_to_array(t2.ancestry, '/')) as a(id)
where t2.id = 39);
Converting the string to an array in order to be able to use the = ANY()
operator is a bit tricky, because you need two levels of parentheses plus a type cast to an integer array to make that work:
select *
from tenants
where id = any ((select string_to_array(t2.ancestry, '/')
from tenants t2
where t2.id = 39)::int[]);