更新列,具有次要ID的非独特ID?

时间:2013-12-28 12:03:03

标签: sql sql-server

+-----+-----+------+----------+
| id  | num | text |  combo   |
+-----+-----+------+----------+
| 126 |   1 |   12 | 12,58,94 |
| 126 |   2 |   58 |          |
| 126 |   3 |   94 |          |
| 130 |   1 |   28 | 28,45,64 |
| 130 |   2 |   45 |          |
| 130 |   3 |   64 |          |
+-----+-----+------+----------+

我有这个表,其中“combo”列当前为null。我试图用“text”中的数据更新它(从“num”中的最小值到最大值以及每个不同的id)

任何有助于制定此查询的帮助都会非常感激,原谅我糟糕的措辞。

2 个答案:

答案 0 :(得分:0)

测试数据

CREATE TABLE #MyTable(id INT,num INT,text INT,combo VARCHAR(100))
GO
INSERT INTO #MyTable
VALUES 
(126,1,12,NULL),
(126,2,58,NULL),
(126,3,94,NULL),
(130,1,28,NULL),
(130,2,45,NULL),
(130,3,64,NULL)
GO

<强>查询

;With UpdateRecord
 AS
   (
   SELECT *  , rn = ROW_NUMBER() OVER (PARTITION BY ID ORDER BY [text])
   FROM #MyTable
   ),
UpdateValues 
AS
(
 SELECT ID, Num,  STUFF(List.Numbers, 1 ,2 , '') Vals
           , rn2 = ROW_NUMBER() OVER (PARTITION BY ID ORDER BY [text])
 FROM #MyTable t CROSS APPLY 
                     (
                      SELECT ', ' + CAST([text] AS VARCHAR) [text()]
                      FROM #MyTable
                      WHERE id = t.id
                      FOR XML PATH('')
                      )List(Numbers)
)
UPDATE UpdateRecord  
SET combo = (SELECT TOP 1 Vals 
             FROM UpdateValues
             WHERE id = UpdateRecord.id AND rn = UpdateRecord.rn
             AND rn = 1)

<强>结果

╔═════════╦═════╦══════╦════════════════╗
║     id  ║ num ║ text ║     combo      ║
╠═════════╬═════╬══════╬════════════════╣
║     126 ║   1 ║   12 ║     12, 58, 94 ║
║     126 ║   2 ║   58 ║     NULL       ║
║     126 ║   3 ║   94 ║     NULL       ║
║     130 ║   1 ║   28 ║     28, 45, 64 ║
║     130 ║   2 ║   45 ║     NULL       ║
║     130 ║   3 ║   64 ║     NULL       ║
╚═════════╩═════╩══════╩════════════════╝

答案 1 :(得分:0)

您可以使用递归cte:

declare @SourceTable TABLE
(
    id int, num int,textvalue varchar(255), combo varchar(255)
)
INSERT INTO @SourceTable(id, num, textvalue) VALUES
(126, 1, 12),(126, 2, 58),(126, 3, 94),(130, 1, 28),(130, 2, 45),(130, 3, 64)

创建一个连接值的递归cte:

;with cte_ConcatenatedText(id, textvalue, num) AS
(
    SELECT id, textvalue, num  FROM @SourceTable WHERE num = 1
    UNION ALL
    SELECT st.id, cast(cte.textvalue + ',' + st.textvalue as varchar(255)), st.num
    FROM @SourceTable st
    INNER JOIN cte_ConcatenatedText cte ON cte.id =  st.id and cte.num = st.num -1
)

之后,您可以更新源表:

UPDATE @SourceTable SET combo = cte.textvalue
FROM @SourceTable st
INNER JOIN
    (SELECT id, textvalue,num FROM cte_ConcatenatedText) cte
ON cte.id = st.id and st.num = 1
INNER JOIN 
    (SELECT id, MAX(num) AS num FROM @SourceTable group by id) maxNum
on maxNum.id = cte.id and maxNum.num = cte.num

SELECT * FROM @SourceTable

结果:

id  num textvalue   combo
126 1   12      12,58,94
126 2   58      NULL
126 3   94      NULL
130 1   28      28,45,64
130 2   45      NULL
130 3   64      NULL