【问题标题】:Concat multiple rows into a comma-delimited value during Update在更新期间将多行连接成逗号分隔的值
【发布时间】:2009-11-05 13:57:23
【问题描述】:

我有一个临时表,其中包含一个名为 Method 的字段,因此:

DECLARE @CaseSites TABLE (
 BriefID  int,
 Method  varchar(60)
 -- other fields
)

方法将从另一个表中的几行填充 - CaseEventTypeList。

跑步

SELECT * FROM CaseEventTypeList WHERE RefID = 1

给予

RefID TypeID
1  2
1  3
1  6

把它变成一个逗号分隔的结果是相当简单的:

DECLARE @CETList varchar(30)

SELECT @CETList = COALESCE(@CETList + ',', '') + CAST(CETL.[TypeID] AS varchar)
FROM CaseEventTypeList CETL 
WHERE CETL.RefID = 1

PRINT @CETList

给予:

2,3,6

现在我需要扩展它以容纳整个表格。这是我想出的:

UPDATE @CaseSites SET Method = COALESCE(Method + ',','') + CAST(CETL.TypeID AS VARCHAR)
 FROM CaseEvents CE
   JOIN CaseEventTypeList AS CETL ON CETL.RefID = CE.TypeListID
 WHERE BriefID = CE.CaseID

但是,这只会用每组值中的第一个值填充 Method。

looked online and found this 但宁愿不使用 udf - 特别是当解决方案感觉如此接近时。

更新: 数据比较简单,RefId 每次递增,TypeID 可以是任意数字,虽然目前只建模了 1 到 8。因此,您可能有:

RefID TypeID
12  2
12  7
13  1
14  1
14  3
14  6

这有望被建模为

SELECT Method from @CaseSites
Method 
...
12  2,7
13  1
14  1,3,6
...

【问题讨论】:

  • 您能否举例说明数据的外观以及您希望输出的外观?我假设 RefID/TypeID 表是传入数据,但我不太确定您希望输出的外观如何。

标签: sql-server-2000 concat


【解决方案1】:

我认为您的问题是因为更新语句每行仅评估“SET Method =”一次,因此您只能在列表中获得一个值。

UDF 将是执行此操作的简单方法,但由于您使用的是临时表,因此这可能不是一个选项,并且您无论如何都希望避免使用它们。因此,您可能需要使用光标(不是很好),但可以按照您想要的方式完成工作。

这是我根据您的原始 sql 提出的。

DECLARE myCURSOR Cursor
FOR
  Select BriefID
  from #CaseSites

Open myCursor
DECLARE @BriefID int
DECLARE @CETList varchar(30)
Fetch NEXT FROM myCursor INTO @BriefID
While (@@FETCH_STATUS <> -1)
BEGIN
  IF (@@FETCH_STATUS <> -2)

  SET @CETList = ''
  SELECT @CETList = COALESCE(@CETList + ',', '') + CAST(CETL.[TypeID] AS varchar)
    FROM #CaseEventTypeList CETL 
   WHERE CETL.RefID = @BriefID 

  UPDATE #CaseSites
     SET Method = @CETList
   WHERE BriefID = @BriefID

  Fetch NEXT FROM myCursor INTO @BriefID
END
CLOSE myCursor
DEALLOCATE myCursor 

【讨论】:

  • 我从没想过为此使用游标。然而,它存在与 UDF 相同的问题 - 缺乏可读性。
  • 无论您做什么,都需要在计划中进行表扫描。选项是公用表表达式、相关子查询、UDF 或游标。 UDF 使 sql 可读,但可能不适用于临时表。
  • 好吧,我实现的 UDF 的代码与我试图在查询中运行的代码完全相同,但工作正常(显然,该语句适用于临时表)。
【解决方案2】:

如果您可以使用 xml,我找到了比我的第一个更好的答案: 使用 xml 的相关子查询。

UPDATE #CaseSites 
   SET Method = (   
                  select  cast([TypeID] as varchar(30))+ ',' 
                    from #CaseEventTypeList
                   where RefID = CE.CaseID 
                     for xml path ('') 
                )
  FROM #CaseEvents CE  

【讨论】:

  • IIANM xml 路径是 2005+ 选项。我们的服务器是一个破旧的 SS2K boxen。
猜你喜欢
  • 2017-06-29
  • 2021-11-28
  • 1970-01-01
  • 1970-01-01
  • 2016-03-13
  • 2012-12-22
  • 2021-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多