SQL:在拆分层次结构中查找缺少的文件夹路径
我有一个包含文件夹路径的表。 此表包含四列:SQL:在拆分层次结构中查找缺少的文件夹路径,sql,sql-server,sql-server-2012,sql-server-performance,Sql,Sql Server,Sql Server 2012,Sql Server Performance,我有一个包含文件夹路径的表。 此表包含四列:DirID、BaseDirID、DirLevel和DisplayPath。 DirID-文件夹的ID。 BaseDirID-层次结构中第一个文件夹的ID。因此,来自同一层次结构的所有文件夹(路径)在此列中共享相同的值。 DirLevel-文件夹的深度。 DisplayPath-文件夹的路径 我需要找到层次结构中这些文件夹之间的所有“间隙” 示例数据,例如: DirID BaseDirID DirLevel DisplayPath 1 1 1 '
DirID
、BaseDirID
、DirLevel
和DisplayPath
。
DirID
-文件夹的ID。
BaseDirID
-层次结构中第一个文件夹的ID。因此,来自同一层次结构的所有文件夹(路径)在此列中共享相同的值。
DirLevel
-文件夹的深度。
DisplayPath
-文件夹的路径
我需要找到层次结构中这些文件夹之间的所有“间隙”
示例数据,例如:
DirID BaseDirID DirLevel DisplayPath
1 1 1 'A'
2 1 3 'A\B\C'
3 1 5 'A\B\C\D\E'
4 1 3 'A\B\F'
5 1 5 'A\B\F\G\H'
6 2 1 'U'
7 2 3 'U\V\W'
8 2 5 'U\V\W\X\Y'
9 2 3 'U\V\M'
10 2 5 'U\V\M\L\O'
因此,我们需要找到以下数据:
BaseDirID DisplayPath
1 'A\B'
1 'A\B\C\D'
1 'A\B\F\G'
2 'U\V'
2 'U\V\W\X'
2 'U\V\M\L'
评论:
a。此表包含超过250000条文件夹记录,因此我们寻求最有效的方法来执行此操作,否则脚本将被卡住很长时间,我们没有时间
b。我没有所有文件夹的列表。我拥有的是“根”文件夹和“叶”文件夹,我需要在层次结构中找到它们之间的“间隙”
c。该表可以包含多个层次结构,我们需要找到所有层次结构中的“间隙”
d。每个层次结构都可以拆分,正如您在示例数据中所看到的,第一个层次结构将拆分为两个文件夹,即“A\B”文件夹的路径:
“A\B\C”和“A\B\F”。
第二个层次结构从“U\V”文件夹拆分为两个文件夹路径:“U\V\W”和“U\V\M”。
我们需要找到所有的“差距”,即使在这种情况下,当层次结构分裂。
e。sql server版本为:sql 2012 SP3
此问题是以下链接中问题的延续问题:
我们的问题还包括以粗体显示的第四条评论
我看到有一种新的列类型,叫做“hierarchyid”(从sql server 2008开始),我认为这可能会帮助我们-
你觉得怎么样
提前感谢。使用此添加的路径
(11,2,'U\V\Z\L\O\Q\R\S\T')
显示路径中缺少的多个文件夹:
with cte as (
select BaseDirID, DisplayPath = left(DisplayPath,len(DisplayPath)-charindex('\',reverse(DisplayPath)))
from t
where DirLevel > 1
and not exists (
select 1
from t i
where t.BaseDirId = i.BaseDirId
and i.DisplayPath = left(t.DisplayPath,len(t.DisplayPath)-charindex('\',reverse(t.DisplayPath)))
)
union all
select BaseDirID, DisplayPath = left(DisplayPath,len(DisplayPath)-charindex('\',reverse(DisplayPath)))
from cte t
where not exists (
select 1
from t i
where t.BaseDirId = i.BaseDirId
and i.DisplayPath = left(t.DisplayPath,len(t.DisplayPath)-charindex('\',reverse(t.DisplayPath)))
)
)
select distinct *
from cte
rextester演示:
返回:
+-----------+-----------------+
| BaseDirID | DisplayPath |
+-----------+-----------------+
| 1 | A\B |
| 1 | A\B\C\D |
| 1 | A\B\F\G |
| 2 | U\V |
| 2 | U\V\M\L |
| 2 | U\V\W\X |
| 2 | U\V\Z |
| 2 | U\V\Z\L |
| 2 | U\V\Z\L\O |
| 2 | U\V\Z\L\O\Q |
| 2 | U\V\Z\L\O\Q\R |
| 2 | U\V\Z\L\O\Q\R\S |
+-----------+-----------------+
真正的文件夹名称不同,或者是A\B…?文件夹名称可以是:Kannan Kannan\Kandasamy Kannan\Kandasamy\Nuriel Kannan\Kandasamy\Nuriel Nuriel\Zrubaveli。确实需要递归丢失的文件夹。解决方案有效吗?因为它在一个包含250000行的表中的每一行上使用CharIndex()多个模块的时间…我在大小~200k的表上尝试了这个解决方案。查询运行了20多分钟,直到我取消它!你能给我一个更有效的解决方案吗?我在问题中写得非常清楚:“这个表包含250000多条文件夹记录,因此我们寻求最有效的方法来实现这一点”。@NurielZrubaly请包括实际的表模式ddl和相关的索引、约束,和问题中的关系以及代表性示例数据。我的表没有任何索引或主键。我现在在
BaseDirID
列中添加了非聚集索引,现在它可以在45秒内运行。但它仍然不够有效。。。请记住,我们可以对表格进行任何更改。我现在补充了一个问题,我们有另一列DirLevel
,表示文件夹的深度。