【问题标题】:SQL Server - Update a column with other column values as CSVSQL Server - 使用其他列值更新列作为 CSV
【发布时间】:2011-07-28 21:28:12
【问题描述】:

表格和样本数据脚本

CREATE TABLE #TEMPTABLE1(ID INT, COL1 NVARCHAR(10))
CREATE TABLE #TEMPTABLE2(ID INT, COL2 NVARCHAR(10))

INSERT INTO #TEMPTABLE1 (ID) VALUES(1)
INSERT INTO #TEMPTABLE1 (ID) VALUES(2)
INSERT INTO #TEMPTABLE1 (ID) VALUES(3)

INSERT INTO #TEMPTABLE2 (ID,COL2) VALUES(1,'A')
INSERT INTO #TEMPTABLE2 (ID,COL2) VALUES(1,'B')
INSERT INTO #TEMPTABLE2 (ID,COL2) VALUES(1,'C')
INSERT INTO #TEMPTABLE2 (ID,COL2) VALUES(2,'X')
INSERT INTO #TEMPTABLE2 (ID,COL2) VALUES(2,'Y')
INSERT INTO #TEMPTABLE2 (ID,COL2) VALUES(3,'Z')

我需要更新#TEMPTABLE1 以便

ID COL1
---------
1  A,B,C 
2  X,Y
3  Z

【问题讨论】:

  • 不要在列中存储 CSV 数据!永远!
  • 乔尔,我没有将 CSV 数据存储在列中。这是报告的一部分,我遇到了这个问题并发布在这里。
  • 如果您不将 CSV 数据存储在列中,那么为什么需要 UPDATE 语句?

标签: sql sql-server sql-server-2005 tsql


【解决方案1】:

听起来 OP 想要一个更新声明。

UPDATE [x]
SET
    [COL1] = STUFF
            (
                (
                    SELECT
                        N',' + [COL2]
                    FROM
                        [#TEMPTABLE2] AS [y]
                    WHERE
                        [y].[ID] = [x].[ID]
                    FOR XML PATH(''), TYPE
                ).value(N'.', N'nvarchar(10)'), 
                1, 1, N''
            )
OUTPUT INSERTED.*
FROM
    [#TEMPTABLE1] AS [x]

【讨论】:

    【解决方案2】:

    看来您问题的关键是根据 id 连接 #temptable2 中的值。 Jeff Moden 在Concatenation Functions and Some Tuning Myths 上有一篇很好的文章@

    虽然整篇文章都非常值得一读,但关键是您可以轻松地将 Stuff 和 For XML Path 与子查询一起使用,以根据 ID 列进行连接。然后您可以轻松地使用它来更新您的#temptable1。

    编辑以添加示例

    串联大致如下:

    SELECT t1.ID,        
    STUFF((SELECT ','+t2.value
       FROM dbo.TestData t2 
       WHERE t1.ID = t2.SomeID FOR XML PATH('')),1,1,'')   
    FROM dbo.TestData t1  
    GROUP BY t1.ID
    

    【讨论】:

    • 在使用 FOR XML 方法时需要注意字符实体化。添加 INSERT INTO #TEMPTABLE2 (ID,COL2) VALUES(3,N'
    【解决方案3】:

    首先创建一个函数:

    CREATE FUNCTION CommaValues(@ID as INT)
    returns varchar(500)
    as
    begin
    DECLARE @DelimList as varchar(500)
    
    select @DelimList = COALESCE(@DelimList + ', ', '') + Col2
    from #TEMPTABLE2
    where ID = @ID
    
    return @DelimList
    end
    

    然后在你的更新中使用它:

    UPDATE #TEMPTABLE1 set Col1 = CommaValues(ID)
    

    【讨论】:

      【解决方案4】:

      这行得通吗:

      INSERT INTO #TEMPTABLE1 SELECT ID,COL2 FROM #TEMPTABLE2 GROUP BY ID
      

      【讨论】:

        【解决方案5】:

        您将无法发出多个插入以更新列(因此将 insertupdate 语句分开)。我看到两个选项:

        插入然后更新

        INSERT INTO #TEMPTABLE2 (ID,COL2) VALUES(1,'A')
        UPDATE #TEMPTABLE2 SET COL2 = COL2 + ',' + B WHERE ID = 1
        UPDATE #TEMPTABLE2 SET COL2 = COL2 + ',' + C WHERE ID = 1
        

        这是相当混乱,但有效。

        插入,但选择到逗号分隔的列表中
        在这种情况下,您可以将主键设置为 ID 和 COL2 的组合(尽管我不确定我是否会推荐这个)并按照上面的操作插入值。然后,当您需要逗号分隔的列表时,选择它,例如,使用 collat​​e(如 Pinal Dave 所述):

        DECLARE @listStr VARCHAR(MAX)
        SELECT @listStr = COALESCE(@listStr+',' ,'') + Name
        FROM Production.Product
        

        【讨论】:

          猜你喜欢
          • 2022-10-18
          • 1970-01-01
          • 1970-01-01
          • 2014-07-11
          • 2015-10-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-01-20
          相关资源
          最近更新 更多