Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/76.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
C# FOREACH递归SQL语句_C#_Sql_Tsql_Sql Server 2008 - Fatal编程技术网

C# FOREACH递归SQL语句

C# FOREACH递归SQL语句,c#,sql,tsql,sql-server-2008,C#,Sql,Tsql,Sql Server 2008,我有一个看起来很简单的问题,但我尝试过的解决方案让我在执行方面有所欠缺。速度看起来很小(不确定我是否满足您的所有要求,但这是一个开始。告诉我它是否符合您的要求,或者是否生成的数字不正确 ;with C as ( select ID, ParentID, ControlNum, ParentControlNum, row_number() over(order by ParentID, ID) - 1 as rn fr

我有一个看起来很简单的问题,但我尝试过的解决方案让我在执行方面有所欠缺。速度看起来很小(不确定我是否满足您的所有要求,但这是一个开始。告诉我它是否符合您的要求,或者是否生成的数字不正确

;with C as
(
  select ID,
         ParentID,
         ControlNum,
         ParentControlNum,
         row_number() over(order by ParentID, ID) - 1 as rn
  from YourTable
)  
update C1
set ControlNum = C1.rn,
    ParentControlNum = case when C1.ParentID is null 
                         then C1.rn
                         else C2.rn 
                       end
from C as C1
  left outer join C as C2
    on C1.ParentID = C2.ID
使用稍微修改的输入在SE数据上运行:

第2版

首先是一个递归CTE
R
,它构建一个字符串,在为
ControlNum
生成值时用作order by。之后,它与上述内容基本相同

;with R as
(
  select ID,
         ParentID,
         cast(ID as varchar(max)) as Sort
  from YourTable
  where ParentID is null
  union all
  select T.ID,
         T.ParentID,
         R.Sort+cast(T.ID as varchar(max))
  from YourTable as T
    inner join R
      on R.ID = T.ParentID
),
C as
(
  select ID,
         ParentID,
         row_number() over(order by Sort) - 1 as rn
  from R
)  
update T
set ControlNum = C1.rn,
    ParentControlNum = case when C1.ParentID is null 
                         then C1.rn
                         else C2.rn 
                       end
from YourTable as T
  inner join C as C1
    on T.ID = C1.ID
  left outer join C as C2
    on T.ParentID = C2.ID
在此处测试:


注意:我想这是处理某些数据的一次性操作,因为您很难添加新节点,同时也很难像这样维护编号。例如,如果您向第一个节点添加新的子节点,则必须为“下面”的所有节点分配all
ControlNum+=1
并重新分配所有的
ParentControlNum

您能添加一些示例数据吗?更新前的样子和更新后的样子。我不清楚“生成ControlNum值以遵守父子关系”是什么意思@MikaelEriksson添加了一点解释的示例数据。这是朝着正确方向迈出的一大步。但这并不能完全解决我的问题,我已将我的问题扩展为更明确的问题。这确实是在处理前对数据进行最终排序的一次重演。这确实有效,但速度稍慢,可能是因为字符串比较。我正在考虑是否可以从第一个版本中获取数据,按ParentControlNum排序,然后在结果上使用row_number()。不管是谁,请考虑一下未来的进展。再次感谢您提供的有效答案。
ID                                      ParentId                                ControlNum  ParentControlNum
8C821027-A6F9-E011-AB48-B499BAE13A62    756F981E-A6F9-E011-AB48-B499BAE13A62    22          21
D7DB6033-A6F9-E011-AB48-B499BAE13A62    756F981E-A6F9-E011-AB48-B499BAE13A62    24          21
D2E36033-A6F9-E011-AB48-B499BAE13A62    C9E36033-A6F9-E011-AB48-B499BAE13A62    58          57
8FE66033-A6F9-E011-AB48-B499BAE13A62    58E66033-A6F9-E011-AB48-B499BAE13A62    69          68
37EC6033-A6F9-E011-AB48-B499BAE13A62    2FEC6033-A6F9-E011-AB48-B499BAE13A62    86          85
41EC6033-A6F9-E011-AB48-B499BAE13A62    2FEC6033-A6F9-E011-AB48-B499BAE13A62    88          85
DDED6033-A6F9-E011-AB48-B499BAE13A62    BCED6033-A6F9-E011-AB48-B499BAE13A62    95          94
DC69981E-A6F9-E011-AB48-B499BAE13A62    NULL                                    0           0
166A981E-A6F9-E011-AB48-B499BAE13A62    NULL                                    1           1
4D6A981E-A6F9-E011-AB48-B499BAE13A62    NULL                                    2           2
856A981E-A6F9-E011-AB48-B499BAE13A62    NULL                                    3           3
F56A981E-A6F9-E011-AB48-B499BAE13A62    NULL                                    4           4
2E6B981E-A6F9-E011-AB48-B499BAE13A62    NULL                                    5           5
666B981E-A6F9-E011-AB48-B499BAE13A62    NULL                                    6           6
9D6B981E-A6F9-E011-AB48-B499BAE13A62    NULL                                    7           7
1
  4
    7
    8
  5
2
  6
3
1
  2
    3
    4
  5
6
  7
8
;with C as
(
  select ID,
         ParentID,
         ControlNum,
         ParentControlNum,
         row_number() over(order by ParentID, ID) - 1 as rn
  from YourTable
)  
update C1
set ControlNum = C1.rn,
    ParentControlNum = case when C1.ParentID is null 
                         then C1.rn
                         else C2.rn 
                       end
from C as C1
  left outer join C as C2
    on C1.ParentID = C2.ID
;with R as
(
  select ID,
         ParentID,
         cast(ID as varchar(max)) as Sort
  from YourTable
  where ParentID is null
  union all
  select T.ID,
         T.ParentID,
         R.Sort+cast(T.ID as varchar(max))
  from YourTable as T
    inner join R
      on R.ID = T.ParentID
),
C as
(
  select ID,
         ParentID,
         row_number() over(order by Sort) - 1 as rn
  from R
)  
update T
set ControlNum = C1.rn,
    ParentControlNum = case when C1.ParentID is null 
                         then C1.rn
                         else C2.rn 
                       end
from YourTable as T
  inner join C as C1
    on T.ID = C1.ID
  left outer join C as C2
    on T.ParentID = C2.ID