SQL基于表替换出现的情况

时间:2015-04-01 14:05:43

标签: sql-server

您好我要解决的SQL问题;我有这些表格:

表a包含varchar列 tst

TST
#&39; 2'&#39 5'&#39 8'
' 2'' 6'
' 4'' 12'

表B包含int列 rep

代表
2
6个

我正在寻找一个查询(没有循环WHILE)以下列方式更新表A:

TST
' R'&#39 5'&#39 8'
' R'' R'
' 4'' 12'

使用char' R'替换表A中表B的出现

提前致谢

2 个答案:

答案 0 :(得分:2)

SQLFiddle Demo

UPDATE t1
SET tst = STUFF(z,1,1,'') --Remove leading comma from final result
FROM (
  SELECT --Convert original string to xml
    tst
   ,CAST('<a>'+REPLACE(tst ,',','</a><a>')+'</a>' AS XML) x
  FROM tst
) t1
CROSS APPLY (
  SELECT --Replace value with 'R' when matched in rep
    ','+CASE WHEN rep IS NULL THEN y.value('.','varchar(max)') ELSE '''R''' END
  FROM x.nodes('a') t2(y) --Explode xml to separate values
  LEFT JOIN rep t3 --Match value to rep
    ON y.value('.','varchar(max)') = QUOTENAME(rep,CHAR(39))
  FOR XML PATH('') --Recompact xml to comma-delimited string
) t4(z)

答案 1 :(得分:0)

通过使用递归CTE来实现它:

;with numbers as (
    SELECT 
       rep, 
       -- processing order
       ROW_NUMBER() OVER (order by  rep) working_order 
    FROM B
), worker as (
    -- Anchor: the first substitution
    SELECT 
       tst, 
       rep,
       -- stores already done substitutions  
       replace(tst, '''' + cast(rep as varchar) + '''', '''R''') tmp_result, 
       1 lvl 
    FROM A JOIN numbers ON working_order=1

    UNION ALL

    -- run through all substitutions to be done
    SELECT 
       w.tst, 
       n.rep, 
       -- use tmp_result to refer to already done substitutions
       replace(w.tmp_result, '''' + cast(n.rep as varchar) + '''', '''R'''), 
       lvl + 1 
    FROM worker w JOIN numbers n ON working_order=lvl+1
), result as (
   SELECT tst, tmp_result FROM worker where lvl = (SELECT MAX(working_order) FROM numbers)
)
UPDATE A SET tst=tmp_result FROM A JOIN result ON result.tst=A.tst 

说明:

  • 首先,我选择B中的所有数字并给它们一个处理编号
  • 在递归CTE worker中,我用顺序替换 由numbers
  • 提供的订单
  • result中,我将工人减少到最后 行(具有最高working_order
  • 的行
  • 最后我使用更新A 结果。