如何筛选SQL表中每个父字符串对应的最长唯一字符串行
解决SQL中筛选最长唯一路径字符串的问题
刚好碰到过类似的路径筛选需求,我来帮你搞定这个问题!你需要的是从路径型数据里挑出最末端的节点——也就是那些没有子路径的记录,之前按反斜杠数量筛选的思路确实有漏洞,毕竟有些末端节点本身层级就少(比如SouthAmerica\\Brazil只有1个反斜杠,但它已经是最底层了)。
核心思路
本质上我们要找的是:不存在其他行的Name以当前行的Name加上反斜杠开头的记录。简单说,当前行的路径不是任何其他行的父路径,它就是最末端的那条。
可行的解决方案
这里给你两种实用的实现方式:
方法1:用NOT EXISTS子查询(最直观高效)
这种方式直接判断当前路径有没有子路径,逻辑清晰,性能也不错:
SELECT t1.Name, t1.SalePrice FROM t1 WHERE NOT EXISTS ( SELECT 1 FROM t1 AS t2 -- 检查是否存在以当前路径为父路径的子路径 WHERE t2.Name LIKE t1.Name + '\\%' );
方法2:结合窗口函数的层级分析(适合需要拓展层级统计的场景)
如果之后还需要用到路径层级的信息,可以先计算每个路径的层级(反斜杠数量+1),再找出每个分支下的最大层级记录:
WITH PathLevels AS ( SELECT Name, SalePrice, -- 计算当前路径的层级:反斜杠的数量 + 1 LEN(Name) - LEN(REPLACE(Name, '\\', '')) + 1 AS Level FROM t1 ) SELECT pl.Name, pl.SalePrice FROM PathLevels pl WHERE pl.Level = ( SELECT MAX(Level) FROM PathLevels pl2 -- 匹配同根分支的所有路径 WHERE pl2.Name LIKE LEFT(pl.Name, CHARINDEX('\\', pl.Name + '\\')) + '%' );
不过如果只是满足当前需求,第一种NOT EXISTS的方法更简洁直接。
测试结果验证
用你提供的测试表运行第一种方法,刚好能得到你想要的输出:
| Name | SalePrice |
|---|---|
| NorthAmerica\US\Northeast\NewYork | 8576 |
| SouthAmerica\Brazil | 1348 |
| SouthAmerica\Chile\NorthEast | 9726 |
| NorthAmerica\Canada\Ontario | 3894 |
为啥之前的LIKE '%\\\\%'不好用?
那个条件只能筛选出包含至少一个反斜杠的行,但没法区分父路径和子路径——比如NorthAmerica\\US\\Northeast确实有反斜杠,但它是父路径,我们需要排除它,因为存在它的子路径NorthAmerica\\US\\Northeast\\NewYork。
内容的提问来源于stack exchange,提问作者2020db9
相关产品推荐
相关产品推荐

