2017-08-16 103 views
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沒有不同的研究,那麼這是預期的結果。 –