Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL:在拆分层次结构中查找缺少的文件夹路径_Sql_Sql Server_Sql Server 2012_Sql Server Performance - Fatal编程技术网

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
,表示文件夹的深度。