[英]Using CTE to update multiple columns in table and loop on all rows in table
我是SQL新手,正在尝试对表中的所有行使用CTE,以使用层次结构信息更新每行中的多个列。 我在网上阅读了许多示例,但都没有一个描述我的确切需求,因此希望有人能帮助我。
我有一张存储在架子->架子->箱子的层次结构中的研究样本表,其中架子是最高级别,箱子是最低级别,样本在箱子下面。 架子,架子和盒子也作为单独的行在此表中。 所有项目都有一个名为“名称”的字段来标识它们。 它们都通过ID和parent_ID连接。 有点像管理结构。
我需要在每一行中填充所有级别值作为样本。 它比我在网上找到的经理-雇员示例更加复杂,并且它需要存储CTE返回的值,而不是像我发现的示例那样简单地执行SELECT来显示它们。
为了在所有行上运行CTE,我已经尝试将整个CTE嵌套在WHILE循环中,但它仅循环单个值而不是所有行。
下面是我目前用于返回一个样本值的层次结构的代码; “ tempspec”是示例表:
DECLARE @TID float;
SET @TID = 39059;
WITH cte AS
(
SELECT ID,
Parent_Id,
Name,
Study_ID,
Loc_Box,
Loc_Shelf,
Loc_Rack,
Loc_Type
FROM tempspec
WHERE ID = @TID and Study_ID = 'XXX'
UNION all
SELECT tempspec.Id,
tempspec.Parent_Id,
tempspec.Name,
tempspec.Study_ID,
tempspec.Loc_Box,
tempspec.Loc_Shelf,
tempspec.Loc_Rack,
tempspec.Loc_Type
FROM tempspec
JOIN cte on tempspec.Id = cte.Parent_Id
)
SELECT E1.name, E1.ID, E1.Parent_ID,E1.Loc_Type,ISNULL(E2.name,'TOP')
FROM cte E1
LEFT JOIN cte E2
ON E1.parent_id = E2.ID;
但是,如果我尝试将SELECT替换为UPDATE,它将运行并说表中的所有行均已更新,但未存储任何内容:
UPDATE E1
SET E1.Loc_Box = E2.Loc_Box,
E1.Loc_Rack = E2.Loc_Rack,
E1.Loc_Shelf = E2.Loc_Shelf
FROM tempspec E1
LEFT JOIN cte E2
ON E1.parent_id = E2.ID;
并且,如果我尝试将CTE嵌套在此WHILE循环中(“ P”表示示例行,因此我仅遍历它们的树),则无法将ID分配给@TID,或者尝试使用它时它永远循环的其他方式:
WHILE EXISTS(SELECT * FROM tempspec WHERE Loc_Type = 'P')
BEGIN
SET @TID = ID;
我究竟做错了什么? 我尝试了各种格式,但似乎无济于事。 在此先感谢您的帮助
以下是要求的测试数据。 我想用样本的父行(类型=“ P”)中的“名称”值填充“架子”,“机架”和“盒子”:
DROP TABLE dbo.TEST_DATA;
CREATE TABLE dbo.TEST_DATA (int ID, int Parent_Id,varchar(30) Name, varchar(10) Type,varchar(30) Shelf,varchar(30) Rack,varchar(30) Box)
INSERT INTO TEST_DATA (39702, 1664, 0228MBDNAERA1, 'P','','','');
INSERT INTO TEST_DATA (39703, 1664, 0230MBDNAERA1, 'P','','','');
INSERT INTO TEST_DATA (39704, 1664, 0231MBDNAERA1, 'P','','','');
INSERT INTO TEST_DATA (39726, 1744, 0228MBDNAERA2, 'P','','','');
INSERT INTO TEST_DATA (39727, 1744, 0230MBDNAERA2, 'P','','','');
INSERT INTO TEST_DATA (39728, 1744, 0231MBDNAERA2, 'P','','','');
INSERT INTO TEST_DATA (39764, 1752, 0228MBDNAERA3, 'P','','','');
INSERT INTO TEST_DATA (39766, 1752, 0230MBDNAERA3, 'P','','','');
INSERT INTO TEST_DATA (39768, 1752, 0231MBDNAERA3, 'P','','','');
INSERT INTO TEST_DATA (1744, 1652, MBDNAERA2 - 3, 'B','','','');
INSERT INTO TEST_DATA (1752, 1732, MBDNAERA3 - 3, 'B','','','');
INSERT INTO TEST_DATA (1664, 1652, MBDNAERA1 - 3, 'B','','','');
INSERT INTO TEST_DATA (1732, 1617, Rack R, 'R','','','');
INSERT INTO TEST_DATA (1652, 1617, Rack Q, 'R','','','');
INSERT INTO TEST_DATA (1617, 2, Shelf 4, 'S','','','');
INSERT INTO TEST_DATA (2, NULL, Freezer, 'F','','','');
一个样本的示例数据层次结构以及我尝试获取的结果行(对格式错误的问题感到抱歉):
ID Parent_Id Name Type Shelf Rack Box
39702 1664 0228MBDNAERA1 'P'
1664 1652 MBDNAERA1 - 3 'B'
1652 1617 Rack Q 'R'
1617 2 Shelf 4 'S'
2 NULL Freezer 'F'
ID Parent_Id Name Type Shelf Rack Box
39702 1664 0228MBDNAERA1 'P' Shelf 4 Rack Q MBDNAERA1 - 3
试试看:
DECLARE @TEST_DATA as TABLE (ID int , Parent_Id int ,Name varchar(30) , Type varchar(10) )
INSERT @TEST_DATA VALUES (39702, 1664, '0228MBDNAERA1', 'P');
INSERT @TEST_DATA VALUES (39703, 1664, '0230MBDNAERA1', 'P');
INSERT @TEST_DATA VALUES (39704, 1664, '0231MBDNAERA1', 'P');
INSERT @TEST_DATA VALUES (39726, 1744, '0228MBDNAERA2', 'P');
INSERT @TEST_DATA VALUES (39727, 1744, '0230MBDNAERA2', 'P');
INSERT @TEST_DATA VALUES (39728, 1744, '0231MBDNAERA2', 'P');
INSERT @TEST_DATA VALUES (39764, 1752, '0228MBDNAERA3', 'P');
INSERT @TEST_DATA VALUES (39766, 1752, '0230MBDNAERA3', 'P');
INSERT @TEST_DATA VALUES (39768, 1752, '0231MBDNAERA3', 'P');
INSERT @TEST_DATA VALUES (1744, 1652, 'MBDNAERA2 - 3', 'B');
INSERT @TEST_DATA VALUES (1752, 1732, 'MBDNAERA3 - 3', 'B');
INSERT @TEST_DATA VALUES (1664, 1652, 'MBDNAERA1 - 3', 'B');
INSERT @TEST_DATA VALUES (1732, 1617, 'Rack R', 'R');
INSERT @TEST_DATA VALUES (1652, 1617, 'Rack Q', 'R');
INSERT @TEST_DATA VALUES (1617, 2, 'Shelf 4', 'S');
INSERT @TEST_DATA VALUES (2, NULL, 'Freezer', 'F');
-- SELECT
;with
cte_product as (
Select * from @TEST_DATA where Type = 'P'),
cte_box as (
Select * from @TEST_DATA where Type = 'B'),
cte_shelf as (
Select * from @TEST_DATA where Type = 'S'),
cte_rack as (
Select * from @TEST_DATA where Type = 'R')
Select * from
cte_product p
left join cte_box b
on
p.Parent_Id = b.ID
inner join cte_rack r
on
b.Parent_Id = r.ID
inner join cte_shelf s
on
r.Parent_Id = s.ID
结果
ID Parent_Id Name Type ID Parent_Id Name Type ID Parent_Id Name Type ID Parent_Id Name Type
----------- ----------- ------------------------------ ---------- ----------- ----------- ------------------------------ ---------- ----------- ----------- ------------------------------ ---------- ----------- ----------- ------------------------------ ----------
39726 1744 0228MBDNAERA2 P 1744 1652 MBDNAERA2 - 3 B 1652 1617 Rack Q R 1617 2 Shelf 4 S
39727 1744 0230MBDNAERA2 P 1744 1652 MBDNAERA2 - 3 B 1652 1617 Rack Q R 1617 2 Shelf 4 S
39728 1744 0231MBDNAERA2 P 1744 1652 MBDNAERA2 - 3 B 1652 1617 Rack Q R 1617 2 Shelf 4 S
39764 1752 0228MBDNAERA3 P 1752 1732 MBDNAERA3 - 3 B 1732 1617 Rack R R 1617 2 Shelf 4 S
39766 1752 0230MBDNAERA3 P 1752 1732 MBDNAERA3 - 3 B 1732 1617 Rack R R 1617 2 Shelf 4 S
39768 1752 0231MBDNAERA3 P 1752 1732 MBDNAERA3 - 3 B 1732 1617 Rack R R 1617 2 Shelf 4 S
39702 1664 0228MBDNAERA1 P 1664 1652 MBDNAERA1 - 3 B 1652 1617 Rack Q R 1617 2 Shelf 4 S
39703 1664 0230MBDNAERA1 P 1664 1652 MBDNAERA1 - 3 B 1652 1617 Rack Q R 1617 2 Shelf 4 S
39704 1664 0231MBDNAERA1 P 1664 1652 MBDNAERA1 - 3 B 1652 1617 Rack Q R 1617 2 Shelf 4 S
--UPDATE TABLE
;with
cte_product as (
Select * from @TEST_DATA where Type = 'P'),
cte_box as (
Select * from @TEST_DATA where Type = 'B'),
cte_shelf as (
Select * from @TEST_DATA where Type = 'S'),
cte_rack as (
Select * from @TEST_DATA where Type = 'R')
UPDATE D
SET
Shelf = S.name
,Rack = r.Name
,Box = b.Name
FROM
@TEST_DATA d
Inner join
cte_product p
left join cte_box b
on
p.Parent_Id = b.ID
inner join cte_rack r
on
b.Parent_Id = r.ID
inner join cte_shelf s
on
r.Parent_Id = s.ID
On
d.ID = p.ID
select * from @TEST_DATA
结果
ID Parent_Id Name Type Shelf Rack Box
----------- ----------- ------------------------------ ---------- ------------------------------ ------------------------------ ------------------------------
39702 1664 0228MBDNAERA1 P Shelf 4 Rack Q MBDNAERA1 - 3
39703 1664 0230MBDNAERA1 P Shelf 4 Rack Q MBDNAERA1 - 3
39704 1664 0231MBDNAERA1 P Shelf 4 Rack Q MBDNAERA1 - 3
39726 1744 0228MBDNAERA2 P Shelf 4 Rack Q MBDNAERA2 - 3
39727 1744 0230MBDNAERA2 P Shelf 4 Rack Q MBDNAERA2 - 3
39728 1744 0231MBDNAERA2 P Shelf 4 Rack Q MBDNAERA2 - 3
39764 1752 0228MBDNAERA3 P Shelf 4 Rack R MBDNAERA3 - 3
39766 1752 0230MBDNAERA3 P Shelf 4 Rack R MBDNAERA3 - 3
39768 1752 0231MBDNAERA3 P Shelf 4 Rack R MBDNAERA3 - 3
1744 1652 MBDNAERA2 - 3 B
1752 1732 MBDNAERA3 - 3 B
1664 1652 MBDNAERA1 - 3 B
1732 1617 Rack R R
1652 1617 Rack Q R
1617 2 Shelf 4 S
2 NULL Freezer F
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.