替换逗号分隔列表中的特定值时,如何避免重复?

时间:2018-12-05 20:49:36

标签: sql sql-server ssms sql-server-2014

我编写了一个查询,该查询将逗号分隔列表中的某个值更新为其他值。我确实知道用逗号分隔列表是非常糟糕的数据库设计,但是在这种情况下,我没有其他选择。

所以查询是

SELECT * FROM AppUser 
WHERE AppValue LIKE '%429%' AND AppCode = 'BI' AND AppName = 'Categories' 
UPDATE AppUser
SET AppValue = REPLACE(AppValue, '429', '506')

现在,上面的查询确实将429替换为506,但是如果那里已经有506,该怎么办。如果我这样查询,将导致重复,并且我将有两个506之类的405,506,565,506而不是405,506,565。 那么,您能指导我如何避免重复吗?

2 个答案:

答案 0 :(得分:0)

您的方法还有另一个问题; REPLACE('123,456,789', '45', 'anything')会在您不想使用时替换。

您还标记了此SSMS(SQL Server)以及MySQL,所以我只是猜测SQL Server ...

UPDATE
  test
SET
  appValue = TRIM(',' FROM REPLACE(source.value, ',406,', replacement.value))
FROM
  test
CROSS APPLY
(
  SELECT ',' + appValue + ','
)
  source(value)
CROSS APPLY
(
  SELECT CASE WHEN source.value LIKE '%,506,%' THEN ',' ELSE ',506,' END
)
  replacement(value)
WHERE
  source.value LIKE '%,406,%'

https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=010d5fb74fbc5c46c201cb13ac753f39

或者,一个更通用的版本...

UPDATE
  test
SET
  appValue = TRIM(',' FROM REPLACE(inputs.expression, inputs.pattern, replacement.value))
FROM
  test
CROSS APPLY
(
  SELECT
    ',' + appValue + ','   AS expression,
    ',' + '406'    + ','   AS pattern,
    ',' + '506'    + ','   AS replacement
)
  inputs
CROSS APPLY
(
  SELECT
    CASE WHEN inputs.expression LIKE '%' + inputs.replacement + '%'
         THEN ','
         ELSE inputs.replacement
     END
)
  replacement(value)
WHERE
  inputs.expression LIKE '%' + inputs.pattern + '%'

https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=9eb71e1e90b07c8c150004dc9a6d5107

答案 1 :(得分:0)

我将创建一个存储过程,该存储过程将创建一个临时表以进行规范化,使用逗号分隔的值填充该表,进行所需的任何更改,然后更新包含规范化的临时临时表中逗号分隔值的字段桌子。

相关问题