1

更新所有行的表圈多列我是新手SQL和我想在一个表中使用CTE的所有行,具有层次信息的每一行中更新多列。我已经在网上阅读了很多例子,但没有一篇描述我需要的东西,所以我希望有人能帮助我。使用CTE表

我存储在的保质>机架>盒,其中架子是最高级别和箱是最低的,低于箱样品的层次研究样本的表。货架,货架和箱子在这个表格中也是分开的行。所有项目都有一个名为'name'的字段来标识它们。它们都通过ID和parent_ID连接。有点像管理结构。

我需要填充所有的电平值的每一行样品英寸这比我在网上找到的管理员和员工示例更复杂,它需要存储CTE返回的值,而不是简单地通过SELECT来显示它们,正如我找到的示例所示。

要在所有行运行CTE,从来就试过在一个while循环嵌套整个CTE,但它只是循环的一个值,而不是所有行。

下面是我现在有工作,返回一个样本值的层次结构中的代码; “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; 

但是,如果我试图通过更新替换选择,它运行并说表中的所有行已被更新,但没有被存储:

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; 

我做错了什么?我试过各种格式,但似乎没有任何工作。在此先感谢您的帮助!

以下是请求的测试数据。我想填充架,机架,和Box与父行的样品名称值(类型=“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 
+1

你可以添加你的表是什么样子样本数据的例子,然后什么结果,你正在从样本数据得到,什么结果,你正在试图获得呢? –

+1

是否要更新每行以从其父项中复制值,还是想要将根(祖先)行的值一直向下推送到层次结构中?在第一种情况下,您根本不需要递归CTE,而在第二种情况下,您需要向递归CTE结果添加额外的列以执行根值。 –

+0

大卫 - 是的,我想更新每一行包含其父母样本(我不需要更新货架/机架/盒行,他们只是建立层次结构)。因此,对于样本A,我希望其货架/货架/箱子值与相应货架/货架/箱子行中的架构/货架/箱子值相匹配。那有意义吗?我认为列出UNION ALL - SELECT语句中的所有列将所有必要的字段拉下来。 – Selene

回答

0

就可以尝试:

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                   
+0

我只是想在CTE之后做一个更新,在那里我将更新该特定样本行的货架,货架和箱子值。是否有可能做到这一点? – Selene

+0

OUTPUT显示没有任何内容保存在Loc_ *列中。 – Selene

+0

如果您对ID没有不同的研究,那么这是预期的结果。 –