如何在SQL中替换一个数字中的一位数?

时间:2018-03-30 09:42:20

标签: sql sql-server

我正在尝试将一组数字改为另一组。

现在:

PRACTICE_ID (FK)         GROUP_ID     ...
0_4_200_400_0.5          4
0_4_300_300_0.5          4
0_4_400_700_0.5          4
0_5_200_400_0.5          5
0_5_900_400_0.5          5
0_5_650_400_0.5          5

应该是:

PRACTICE_ID (FK)         GROUP_ID     ...
*0_5_200_400_0.5         4
0_5_300_300_0.5          4
0_5_400_700_0.5          4
*0_5_200_400_0.5         5
0_5_900_400_0.5          5
0_5_650_400_0.5          5

我使用查询来达到目标​​:

UPDATE CUSTOM_PRACTICE
SET PRACTICE_ID = REPLACE(PRACTICE_ID, '0_4', '0_5')
WHERE GROUP_ID = 4

在这种情况下,我无法复制值。我试图使用NOT EXISTS子句但没有得到结果

如何重写所有没有重复的值?像这样:

PRACTICE_ID (FK)         GROUP_ID     ...
0_4_200_400_0.5          4
0_5_300_300_0.5          4
0_5_400_700_0.5          4
0_5_200_400_0.5          5
0_5_900_400_0.5          5
0_5_650_400_0.5          5

2 个答案:

答案 0 :(得分:0)

UPDATE CUSTOM_PRACTICE
SET PRACTICE_ID = REPLACE(PRACTICE_ID, '0_4', '0_5')
WHERE GROUP_ID = 4 AND REPLACE(PRACTICE_ID, '0_4', '0_5') NOT IN
   (SELECT PRACTICE_ID FROM CUSTOM_PRACTICE)

答案 1 :(得分:0)

SQL Server为这个名为STUFF()的函数提供了非常方便的功能。执行所需操作的一种方法是使用NOT EXISTS

UPDATE CUSTOM_PRACTICE
    SET PRACTICE_ID = STUFF(PRACTICE_ID, 3, 1, '5')
    WHERE PRACTICE_ID LIKE '0_4%' AND
          NOT EXISTS (SELECT 1
                      FROM CUSTOM_PRACTICE CP2
                      WHERE CP2.PRACTICE_ID = STUFF(PRACTICE_ID, 3, 1, '5') AND
                            STUFF(PRACTICE_ID, 3, 1, '5')
                     );

请注意REPLACE(PRACTICE_ID, '0_4', '0_5')并不能真正做到你想要的,因为:

REPLACE('0_4_200_400_0.5', '0_4', '0_5')

返回:

'0_5_200_500_0.5'

'0_4_200_400_0.5'

但是,我想我喜欢使用可更新的CTE,因为逻辑只出现在一个地方:

with toupdate as (
      select cp.*
             (case when practice_id like '0_4%' then stuff(practice_id, 3, 1, '5')
                   else practice_id
              end) as new_practice_id
      from custom_practice cp
     )
update t
    set practice_id = new_practice_id
    from (select t.*, count(*) over (partition by new_practice_id) as cnt
          from toupdate
         )
    where practice_id <> new_practice_id and cnt = 1;