正在自引用中执行批量更新 table

Performing batch update in self referencing table

我有一个自引用的 table(项目),其中有一个可为空的 ReferenceId 列。这是最大两级层次结构,具有父级 (Type = 0) 和可能的子级 (Type = 1)。

Example of Items Parent record: ReferenceId = null  Type = 0
Example of Items Child record: ReferenceId = Id of Parent   Type = 1

目前 table 中的参考数据已损坏。我可以通过编写一个小软件来恢复引用,但我想知道我是否可以使用 SQL(或 Linq)查询来一次性完成它。

要了解需要做什么,还有一个Containertable,它和Items是一对多的关系

因此,项目 table 中的重要列将是 Id、ContainerId、ReferenceId 和 Type

我需要的是:

UPDATE Items SET Referenceid = ?
FROM Items WHERE Type = 1

?应该是 Items 父记录的 ID,它与子记录在同一个容器中。

只有当容器中只有 1 个父记录时,子项才应该更新。

所以,如果我有这样的结构:

Id   ContainerId     Referenceid      Type
1     1                NULL             0
2     1                NULL             0
3     1                NULL             1

我不应该执行更新,因为容器 Id=1(Id=1 和 Id=2)中有两个父记录(Type=0)。

所以,如果我有这样的结构:

Id   ContainerId     Referenceid      Type
1     1                NULL             0
2     1                NULL             1
3     1                NULL             1

我应该同时更新 Id=2 和 Id=3,设置 ReferenceId = 1,因为容器中只有 1 个父级。

我希望这是清楚的。有什么想法吗?

使用 common table expression 仅获取容器唯一父项的那些父项,然后使用具有通用 table 表达式的 inner join

;with p as (
  select 
      Id = min(Id)
    , ContainerId     
  from Items p
  where [Type] = 0
  group by ContainerId
  having count(*) = 1 /* <-- containers with only 1 parent */
)
update c
  set c.ReferenceId = p.Id
from Items c
  inner join p 
    on c.ContainerId = p.ContainerId
where c.Type = 1;

rextester 演示:http://rextester.com/CDOIN71171

项目行:

 (1,1,null,0) /* <-- 1 parent  in container 1 */
,(2,1,null,1)
,(3,1,null,1)
,(4,2,null,0) /* <-- 2 parents in container 2 */
,(5,2,null,0)
,(6,2,null,1)

returns:

+----+-------------+-------------+------+
| id | containerid | referenceid | type |
+----+-------------+-------------+------+
|  1 |           1 | NULL        |    0 |
|  2 |           1 | 1           |    1 |
|  3 |           1 | 1           |    1 |
|  4 |           2 | NULL        |    0 |
|  5 |           2 | NULL        |    0 |
|  6 |           2 | NULL        |    1 |
+----+-------------+-------------+------+