我有一个带有可空的ReferenceId列的自引用表(Items)。这是一个最大的两级层次结构,父级(Type = 0)和可能的子级(Type = 1)。
Example of Items Parent record: ReferenceId = null Type = 0
Example of Items Child record: ReferenceId = Id of Parent Type = 1
目前表中的参考数据已被破坏。我可以通过编写一个小软件来恢复引用,但我想知道我是否可以使用SQL(或Linq)查询在一个批处理中执行它。
要了解需要做什么,还有一个容器表,它与Items有1对多的关系。
因此,Items表中的重要列将是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个父级。
我希望这很清楚。有什么想法吗?
答案 0 :(得分:1)
使用common table expression仅获取容器的唯一父项,然后使用带有公用表表达式的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)
返回:
+----+-------------+-------------+------+
| 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 |
+----+-------------+-------------+------+