Sql 我需要一个以我的名字开头但没有';I don’那一组中没有一个是从一开始的

Sql 我需要一个以我的名字开头但没有';I don’那一组中没有一个是从一开始的,sql,sqlite,Sql,Sqlite,假设我有一个名为“name”的文本主键表。给定一个名称(可能包含包括%在内的任意字符),我需要该表中所有以该名称开头、长于该名称且不以该表中任何长于给定名称的行开头的行 例如,假设我的表包含名称ad、add、adder和格言。如果我查询“广告之子”,我想返回add,adage。(adder是add的子项)。我有几百万行,这能有效地完成吗?递归查询当然是可用的 目前我有一种不同的方法,即维护一个“父”列。维护此列的代码非常痛苦,如果此其他方法合理,则不需要此代码。您可以在列上使用左键,如下所示:

假设我有一个名为“name”的文本主键表。给定一个名称(可能包含包括%在内的任意字符),我需要该表中所有以该名称开头、长于该名称且不以该表中任何长于给定名称的行开头的行

例如,假设我的表包含名称
ad
add
adder
格言。如果我查询“广告之子”,我想返回
add
adage
。(
adder
add
的子项)。我有几百万行,这能有效地完成吗?递归查询当然是可用的


目前我有一种不同的方法,即维护一个“父”列。维护此列的代码非常痛苦,如果此其他方法合理,则不需要此代码。

您可以在列上使用左键,如下所示:

 select *
 from sometable
 where lower(left(name,2)) = 'ad' and length(name) > 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 || '_%'
);
请参阅。
相当于上述具有自左联接的查询:

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
请参阅。
结果:


这个查询没有完成消除子对象中的子对象的困难部分。sorry@Brannon啊,我第一次读它的时候不理解这个要求。它不必是递归的。我不清楚这是否是唯一的方法。为什么它应该是递归的?对于2个级别,您的意思是什么?你能发布它不起作用的示例数据吗?是的,我明白你的意思-%处理所有问题。从测试来看,上面的查询比“外部连接”查询快很多。但是,对于我目前的需要来说,它仍然太慢,在一个包含81k个项目的表上执行大约需要5秒钟。请在没有CTE的情况下尝试:唉,它仍然太慢。
| name  |
| ----- |
| add   |
| adage |