SQLServer如何在文本列上查找叶

时间:2019-03-05 10:18:15

标签: sql-server

我正试图从SqlServer表中获取叶子节点,如下所示:

Id       |Text
-----------------
01      |dasdasd
01.01   |asaasa
01.02   |dasdd
01.02.01|ddada
02      |sdad

作为结果,我希望此表仅具有叶节点...

Id      |Text
----------------
01.01   |asaasa
01.02.01|ddada
02      |sdad

感谢帮助

2 个答案:

答案 0 :(得分:0)

数据:

drop table if exists #test
create table #test (id varchar(20), text varchar(30))
insert #test values ('01', 'dasdasd')
                  , ('01.01', 'asaasa')
                  , ('01.02', 'dasdd')
                  , ('01.02.01', 'ddada')
                  , ('02', 'sdad')

查询:

select id, text from #test t1
cross apply (
    select count(*) cnt from #test t2 where t2.id like  t1.id + '%'
) calc
where calc.cnt = 1

输出:

id        text
01.01     asaasa
01.02.01  ddada
02        sdad

答案 1 :(得分:0)

您可以利用Id的层次结构表示来查找没有其他以其ID开头的行的行:

create table #table1 (id varchar(40) primary key,Text varchar(200))

insert into #table1 (id,text)
values 
('01','dasdasd'),
('01.01','asaasa'),
('01.02','dasdd'),
('01.02.01','ddada'),
('02','sdad')


SELECT t1.*,t2.* 
FROM #table1 t1 LEFT OUTER JOIN #table1 t2 
    ON t2.id LIKE t1.id + '%' 
        AND t1.id!=t2.id
WHERE t2.id IS NULL

t2.id like t1.id + '%'将找到t1的后代,而t1.id!=t2.id确保同一行不匹配。最后t2.id is null放弃所有匹配项,仅留下叶子行。结果是:

id       Text
01.01    asaasa
01.02.01 ddada
02       sdad

最好用实际的hierarchyid列替换层次结构字符串。首先,该字符串每个级别最多只能使用99个节点。添加更多节点将需要重写所有密钥。其次,需要使用字符串操作来查找叶子,祖先,级别等。

等效表如下所示:

create table #table2 (id hierarchyid primary key,Text varchar(200))

insert into #table2 (id,text)
values 
('/1/','dasdasd'),
('/1/1/','asaasa'),
('/1/2/','dasdd'),
('/1/2/1/','ddada'),
('/2/','sdad')

使用GetAncestor()函数而不是LIKE ..来获取叶子节点的方式与以前类似:

SELECT t1.Id.ToString(), t1.Text
FROM #table2 t1 LEFT OUTER JOIN #table2 t2
  ON t1.Id = t2.Id.GetAncestor(1)
WHERE t2.Id IS NULL;

添加节点级别是微不足道的,甚至不会影响执行计划。不过,在上一个查询中执行相同的操作将需要对ID字段中的点进行计数:

SELECT t1.Id.ToString() As ID, t1.Id.GetLevel() As Level,t1.Text
FROM #table2 t1 LEFT OUTER JOIN #table2 t2
  ON t1.Id = t2.Id.GetAncestor(1)
WHERE t2.Id IS NULL;

这次的结果是:

ID      Level   Text
/1/1/   2       asaasa
/1/2/1/ 3       ddada
/2/     1       sdad
相关问题