假设我有一个带有文本主键的表,称为“名称”。给定一个名称(可以包含任何包含%的任意字符)的名称,我需要该表中所有以该名称开头,比该名称更长,并且不以该表格中其他任何内容开头的行比给定的名字。
例如,假设我的表包含名称ad
,add
,adder
和adage
。如果我查询“广告的子代”,我想返回add
,adage
。 (adder
是add
的子代)。我有几百万行,可以有效地完成吗?递归查询当然可用。
我目前有一个不同的方法,即我维护一个“父”列。维护该专栏的代码很痛苦,并且如果这种其他方法合理的话,那将是不必要的。
答案 0 :(得分:2)
我不能说出它的效率,但我认为它可以工作:
with cte as (
select name
from tablename
where name like 'ad' || '_%'
)
select c.name
from cte c
where not exists (
select 1 from cte
where c.name like name || '_%'
);
请参见demo。
等同于具有自我LEFT JOIN的上述查询:
with cte as (
select name
from tablename
where name like 'ad' || '_%'
)
select c.name
from cte c left join cte cc
on c.name like cc.name || '_%'
where cc.name is null
请参见demo。
结果:
| name |
| ----- |
| add |
| adage |
答案 1 :(得分:0)
您可以像这样在列上使用left:
select *
from sometable
where lower(left(name,2)) = 'ad' and length(name) > 2