SQL如果单元格中至少有两个已定义的值,则替换一个单元格中的值

时间:2016-02-11 17:32:22

标签: mysql sql regex replace

我有一个我必须处理的列/变量。此列的单元格包含一些值,例如字母。如果单元格包含来自定义字母集的至少两个字母,例如abcd,那么所有这些特定字母都应替换为M

这是一个最小的例子。 string是要处理的字段,结果应包含已处理的字符串:

-- Table
CREATE TABLE x0 (
string    VARCHAR(255)
, result  VARCHAR(255)
);

-- Values (after values is the desired result)
INSERT INTO x0(string) VALUES 
  ('--a---')         -- '--a--'
, ('-c')             -- '-c'
, ('a-d')            -- 'M-'
, ('b--cd')          -- 'M--'
, ('--c---d')        -- '--M---'
;

这是我的第一次尝试(只考虑string a,以避免代码过长):

UPDATE x0 SET result = NULL;    
UPDATE x0
SET result = string
    , result = CASE WHEN string REGEXP 'a' AND string  NOT REGEXP '[bcd]' THEN result ELSE result END
    , result = CASE WHEN string REGEXP 'a' AND string  REGEXP '[bcd]' THEN REPLACE(result,'a','M') ELSE result END
    , result = CASE WHEN string REGEXP 'a' AND string  REGEXP '[bcd]' THEN REPLACE(result,'b','M') ELSE result  END 
    , result = CASE WHEN string REGEXP 'a' AND string  REGEXP '[bcd]' THEN REPLACE(result,'c','M') ELSE result  END
    , result = CASE WHEN string REGEXP 'a' AND string  REGEXP '[bcd]' THEN REPLACE(result,'d','M') ELSE result END
;
SELECT * FROM x0;

结果如下:

string  result
--a---  --a---
-c      -c
a-d     M-M
b--cd   b--cd
--c---d --c---d

我有两个问题需要解决:

  1. 我的代码非常具体,我必须为每个可能的组合写CASE WHEN。对于一般情况,是否有一种聪明的方法可以做到这一点?
  2. 当我获得每个abcd M时,我如何删除所有M但第一个?
  3. 感谢您的帮助。

    以下是代码的长版本。想象一下,这个集合不仅包含4个字母,还包含15个字母。

    UPDATE x0
    SET result = string
        , result = CASE WHEN string REGEXP 'a' AND string  NOT REGEXP '[bcd]' THEN result ELSE result END
        , result = CASE WHEN string REGEXP 'a' AND string      REGEXP '[bcd]' THEN REPLACE(result,'a','M') ELSE result END
        , result = CASE WHEN string REGEXP 'a' AND string      REGEXP '[bcd]' THEN REPLACE(result,'b','M') ELSE result  END 
        , result = CASE WHEN string REGEXP 'a' AND string      REGEXP '[bcd]' THEN REPLACE(result,'c','M') ELSE result  END
        , result = CASE WHEN string REGEXP 'a' AND string      REGEXP '[bcd]' THEN REPLACE(result,'d','M') ELSE result END
    
        , result = CASE WHEN string REGEXP 'b' AND string  NOT REGEXP '[acd]' THEN result ELSE result END
        , result = CASE WHEN string REGEXP 'b' AND string      REGEXP '[acd]' THEN REPLACE(result,'a','M') ELSE result END
        , result = CASE WHEN string REGEXP 'b' AND string      REGEXP '[acd]' THEN REPLACE(result,'b','M') ELSE result  END 
        , result = CASE WHEN string REGEXP 'b' AND string      REGEXP '[acd]' THEN REPLACE(result,'c','M') ELSE result  END
        , result = CASE WHEN string REGEXP 'b' AND string      REGEXP '[acd]' THEN REPLACE(result,'d','M') ELSE result END
    
        , result = CASE WHEN string REGEXP 'c' AND string  NOT REGEXP '[abd]' THEN result ELSE result END
        , result = CASE WHEN string REGEXP 'c' AND string      REGEXP '[abd]' THEN REPLACE(result,'a','M') ELSE result END
        , result = CASE WHEN string REGEXP 'c' AND string      REGEXP '[abd]' THEN REPLACE(result,'b','M') ELSE result  END 
        , result = CASE WHEN string REGEXP 'c' AND string      REGEXP '[abd]' THEN REPLACE(result,'c','M') ELSE result  END
        , result = CASE WHEN string REGEXP 'c' AND string      REGEXP '[abd]' THEN REPLACE(result,'d','M') ELSE result END
    
        , result = CASE WHEN string REGEXP 'd' AND string  NOT REGEXP '[abc]' THEN result ELSE result END
        , result = CASE WHEN string REGEXP 'd' AND string      REGEXP '[abc]' THEN REPLACE(result,'a','M') ELSE result END
        , result = CASE WHEN string REGEXP 'd' AND string      REGEXP '[abc]' THEN REPLACE(result,'b','M') ELSE result  END 
        , result = CASE WHEN string REGEXP 'd' AND string      REGEXP '[abc]' THEN REPLACE(result,'c','M') ELSE result  END
        , result = CASE WHEN string REGEXP 'd' AND string      REGEXP '[abc]' THEN REPLACE(result,'d','M') ELSE result END
    
    ;
    SELECT * FROM x0;
    
    string  result
    --a---  --a---
    -c  -c
    a-d     M-M
    b--cd   M--MM
    --c---d --M---M
    

1 个答案:

答案 0 :(得分:0)

我找到了可能的答案,但仍然不完美。首先,我将每个定义的角色添加到M。然后我计算M,如果有多于1,则删除a,b,c,d。

UPDATE x0 SET result = NULL;
UPDATE x0
SET result = string
    , result = REPLACE(result,'a','Ma')
    , result = REPLACE(result,'b','Mb')
    , result = REPLACE(result,'c','Mc')
    , result = REPLACE(result,'d','Md')
, result = CASE 
           WHEN CHAR_LENGTH(result) - CHAR_LENGTH(REPLACE(result,'M','')) > 1 
       THEN REPLACE(REPLACE(REPLACE(REPLACE(result,'a',''),'b',''),'c',''),'d','')
       ELSE REPLACE(result,'M','') END
    , result = CONCAT(SUBSTR(result,1,POSITION('M' IN result)),REPLACE(SUBSTR(result,POSITION('M' IN result)+1),'M',''))

;
SELECT * FROM x0;


string  result
--a---  --a---
-c      -c
a-d     M-
b--cd   M--
--c---d --M---

MariaDB版本> = 10还有函数REGEXP_REPLACE(subject, pattern, replace),可以解决这类问题。