SQL Server:通过查找其他表替换字段中的值

时间:2014-10-30 09:39:06

标签: sql sql-server

我目前正在遇到一个可能有一个简单解决方案的挑战,但不知怎的,我无法想出它。

我的表A有两个字段,格式如下:

[ID]   [Codes]
 1      A;B
 2      D  
 3      A;C

表B的格式如下:

[ID]   [Codes]
 A     Apple
 B     Orange  
 C     Pear
 D     Strawberry

我想做的是查找/替换以生成以下输出

a.[ID]   a.[Parsed_Codes]
  1     Apple;Orange
  2     Strawberry 
  3     Apple;Pear

简而言之,我想用表B中的代码替换表A中的代码。

当然我可以写一个很长的替换语句(在我的例子中有几百个代码),但这似乎是一种非常低效的方法。

谢谢!

2 个答案:

答案 0 :(得分:1)

简单方法是转换表A [代码] column data(csv) into separate rows. 然后使用表B 加入以获取相应的代码。最后convert the rows to CSV得到结果。试试这个。

CREATE TABLE #tablea
  ([ID]    INT,[Codes] VARCHAR(100))

INSERT INTO #tablea
VALUES      (1,'A;B'),(2,'D' ),(3,'A;C')

CREATE TABLE #tableB
  ([ID]    VARCHAR(100),[Codes] VARCHAR(100))

INSERT INTO #tableb
VALUES      ('A','Apple'),( 'B','Orange' ),
            ('C','Pear'),('D','Strawberry')

SELECT a.id,
       a.Codes old_code,
       b.Codes Parsed_Codes
INTO   #final
FROM   #tableb b
       JOIN (SELECT id,
                    codes,
                    Split.a.value('.', 'VARCHAR(100)') [new_Codes]
             FROM   (SELECT id,
                            [Codes],
                            Cast ('<M>' + Replace([Codes], ';', '</M><M>')
                                  + '</M>' AS XML) AS Data
                     FROM   #tablea) AS A
                    CROSS APPLY Data.nodes ('/M') AS Split(a)) a
         ON a.new_Codes = b.id

SELECT t1.ID,
       old_code,
       Stuff((SELECT '; ' + CONVERT(VARCHAR, Parsed_Codes)
              FROM   #final b
              WHERE  b.ID = t1.ID
              FOR XML PATH('')), 1, 2, '')
FROM   #final t1
GROUP  BY t1.id,
          old_code 

<强>输出

ID  old_code    Parsed_Codes
--  --------    ------------
1   A;B         Apple; Orange
2   D           Strawberry
3   A;C         Apple; Pear

(注意:可以避免临时表以避免代码混淆我使用临时表)

答案 1 :(得分:0)

首先创建此函数..它用于将分隔的字符串拆分为变量表。然后我们就可以使用这个函数来确定另一个表中的代码,并使用STUFF函数将它们作为一个字符串返回。

CREATE FUNCTION [dbo].[fnSplitString]
   (
    @string NVarchar(MAX)
   ,@delimiter Char(1) = ','
   )
RETURNS @t TABLE (string NVarchar(MAX))
AS
BEGIN 
   DECLARE @pos Int
   DECLARE @piece Varchar(500)

   IF RIGHT(RTRIM(@string), 1) <> @delimiter
      SET @string = @string + @delimiter

   SET @pos = PATINDEX('%' + @delimiter + '%', @string)
   WHILE @pos <> 0
      BEGIN
         SET @piece = LEFT(@string, @pos - 1) 
         INSERT   @t
                  SELECT   @piece

         SET @string = STUFF(@string, 1, @pos, '')
         SET @pos = PATINDEX('%' + @delimiter + '%', @string)
      END 

   RETURN
END

然后运行以下查询...

DECLARE @result TABLE
   (
    [ID] Int
   ,[CommaDelimitedCodes] Varchar(500)
   )
DECLARE @codes TABLE
   (
    [ID] Varchar(500)
   ,[FullNames] Varchar(500)
   )
INSERT   INTO @result
         SELECT   1
                 ,'A;B'
INSERT   INTO @result
         SELECT   2
                 ,'D'
INSERT   INTO @result
         SELECT   3
                 ,'A;C'

INSERT   INTO @codes
         SELECT   'A'
                 ,'Apple'
INSERT   INTO @codes
         SELECT   'B'
                 ,'Orange'
INSERT   INTO @codes
         SELECT   'C'
                 ,'Pear'
INSERT   INTO @codes
         SELECT   'D'
                 ,'Strawberry'

SELECT   * 
        ,STUFF((
                SELECT  ', ' + [FullNames]
                FROM    @codes t
                WHERE   id IN (SELECT  *
                               FROM    dbo.fnSplitString(r.[CommaDelimitedCodes], ';'))
               FOR
                XML PATH('')
               ), 1, 2, '') AS taglist
FROM     @result AS r  

我创建了两个要测试的变量表 - 但显然在你的情况下你需要用表中的实际字段名替换它们。