使用正则表达式替换Mysql

使用正则表达式替换Mysql,mysql,regex,string,Mysql,Regex,String,我有一个如下的问题 SELECT FIELDATA FROM DATASET WHERE CATID = 2; 输出为 21@Marketing;76@Sales 如果数据库没有存储多个值,则输出也可以如下所示 21@Marketing 我尝试了以下方法 SELECT SUBSTRING_INDEX(FIELDATA, '@', -1) AS FIELDATA FROM DATASET WHERE CATID = 2; 但它并没有给出预期的结果 是否可以执行字符串操作以使输出变为 营销

我有一个如下的问题

SELECT FIELDATA FROM DATASET WHERE CATID = 2;
输出为

21@Marketing;76@Sales
如果数据库没有存储多个值,则输出也可以如下所示

21@Marketing
我尝试了以下方法

SELECT SUBSTRING_INDEX(FIELDATA, '@', -1) AS FIELDATA FROM DATASET WHERE CATID = 2; 
但它并没有给出预期的结果

是否可以执行字符串操作以使输出变为 营销,前者是销售,而后者只是营销

总结输入的模式

 number1@text1;number2@text2;number3@text; 
输出应该是

 text1, text2, text3

显然,基于当前的MySQL函数,没有简单的方法可以满足您的期望

下面是一个符合您期望的简单解决方案,它基于@and;分隔符

示例SQL:

-- data
CREATE TABLE test.DATASET ( ID INT NOT NULL, U_NAME VARCHAR(45) NULL, FIELDATA VARCHAR(255) NULL, PRIMARY KEY (ID)); 
INSERT INTO test.DATASET (ID, U_NAME, FIELDATA) VALUES ('1', 'ALPHA', '21@Marketing;31@Sales'); 
INSERT INTO test.DATASET (ID, U_NAME, FIELDATA) VALUES ('2', 'BETA', '21@Marketing');

-- Query wanted, which can handle up to 5 secsions
SELECT 
    FIELDATA, 
    CONCAT_WS(
        ', ',
        IF((@tmp:=SUBSTRING_INDEX( SUBSTRING_INDEX(FIELDATA, '@', -5), ';', 1)) LIKE '%@%', NULL, @tmp),
        IF((@tmp:=SUBSTRING_INDEX( SUBSTRING_INDEX(FIELDATA, '@', -4), ';', 1)) LIKE '%@%', NULL, @tmp),
        IF((@tmp:=SUBSTRING_INDEX( SUBSTRING_INDEX(FIELDATA, '@', -3), ';', 1)) LIKE '%@%', NULL, @tmp),
        IF((@tmp:=SUBSTRING_INDEX( SUBSTRING_INDEX(FIELDATA, '@', -2), ';', 1)) LIKE '%@%', NULL, @tmp),
        IF((@tmp:=SUBSTRING_INDEX( SUBSTRING_INDEX(FIELDATA, '@', -1), ';', 1)) LIKE '%@%', NULL, @tmp)
    ) output
FROM  test.DATASET JOIN (SELECT @tmp := NULL) v;
-需要查询,最多可处理2个分离 选择 菲尔德塔塔, 海螺 ', ', IF@tmp:=SUBSTRING_INDEX SUBSTRING_indexfielddata,'@',-2,';',1,如“@%”,NULL,@tmp, IF@tmp:=SUBSTRING_INDEX SUBSTRING_indexfielddata,'@',-1,';',1类似“@%”,NULL,@tmp 输出 从test.DATASET连接选择@tmp:=NULL v

输出:

mysql> -- Query wanted, which can handle up to 5 secsions
mysql> SELECT
    ->     FIELDATA,
    ->     CONCAT_WS(
    ->         ', ',
    ->         IF((@tmp:=SUBSTRING_INDEX( SUBSTRING_INDEX(FIELDATA, '@', -5), ';', 1)) LIKE '%@%', NULL, @tmp),
    ->         IF((@tmp:=SUBSTRING_INDEX( SUBSTRING_INDEX(FIELDATA, '@', -4), ';', 1)) LIKE '%@%', NULL, @tmp),
    ->         IF((@tmp:=SUBSTRING_INDEX( SUBSTRING_INDEX(FIELDATA, '@', -3), ';', 1)) LIKE '%@%', NULL, @tmp),
    ->         IF((@tmp:=SUBSTRING_INDEX( SUBSTRING_INDEX(FIELDATA, '@', -2), ';', 1)) LIKE '%@%', NULL, @tmp),
    ->         IF((@tmp:=SUBSTRING_INDEX( SUBSTRING_INDEX(FIELDATA, '@', -1), ';', 1)) LIKE '%@%', NULL, @tmp)
    ->     ) output
    -> FROM  test.DATASET JOIN (SELECT @tmp := NULL) v;
+-----------------------+------------------+
| FIELDATA              | output           |
+-----------------------+------------------+
| 21@Marketing;31@Sales | Marketing, Sales |
| 21@Marketing          | Marketing        |
+-----------------------+------------------+
2 rows in set (0.00 sec)

mysql> -- Query wanted, which can handle up to 2 secsions
mysql> SELECT
    ->     FIELDATA,
    ->     CONCAT_WS(
    ->         ', ',
    ->         IF((@tmp:=SUBSTRING_INDEX( SUBSTRING_INDEX(FIELDATA, '@', -2), ';', 1)) LIKE '%@%', NULL, @tmp),
    ->         IF((@tmp:=SUBSTRING_INDEX( SUBSTRING_INDEX(FIELDATA, '@', -1), ';', 1)) LIKE '%@%', NULL, @tmp)
    ->         ) output
    -> FROM test.DATASET JOIN (SELECT @tmp := NULL) v;
+-----------------------+------------------+
| FIELDATA              | output           |
+-----------------------+------------------+
| 21@Marketing;31@Sales | Marketing, Sales |
| 21@Marketing          | Marketing        |
+-----------------------+------------------+
2 rows in set (0.00 sec)

这是我对你的问题的初步看法。我在web上找到了一些函数,稍后我将添加这些函数,并将它们组合起来,以满足您的特定需要:您需要获得一个带有两级分隔符@and;的干净字符串

见下文:

DELIMITER $$

CREATE FUNCTION splitter(x VARCHAR(255), delim VARCHAR(12), pos INT)
RETURNS VARCHAR(255)
RETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(x, delim, pos),
       LENGTH(SUBSTRING_INDEX(x, delim, pos -1)) + 1),
       delim, '');
END$$

CREATE FUNCTION substrCount(s VARCHAR(255), ss VARCHAR(255)) 
RETURNS tinyint(3) unsigned
READS SQL DATA
BEGIN
  DECLARE count TINYINT(3) UNSIGNED;
  DECLARE offset TINYINT(3) UNSIGNED;
  DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET s = NULL;
  SET count = 0;
  SET offset = 1;
  REPEAT
    IF NOT ISNULL(s) AND offset > 0 THEN
      SET offset = LOCATE(ss, s, offset);
      IF offset > 0 THEN
        SET count = count + 1;
        SET offset = offset + 1;
      END IF;
    END IF;
   UNTIL ISNULL(s) OR offset = 0 END REPEAT;
   RETURN count;
END$$

CREATE FUNCTION split_str(x varchar(255), delim varchar(12), delim2 varchar(12), return_separator varchar(12)) RETURNS varchar(255)
BEGIN
  SET @Valcount = substrCount(x,delim)+1;
  SET @v1=0;
  SET @v2='';
  WHILE (@v1 < @Valcount) DO
    set @val = splitter(x,delim,@v1+1);
    if @v1 = 0 then
      SET @v2 = world.split_str(@val,delim2,2);
    else
      SET @v2 = concat(@v2,return_separator,world.split_str(@val,delim2,2));
    end if;
    SET @v1 = @v1 + 1;
  END WHILE;
  return @v2;
END$$
DELIMITER ;
结果将是:

text1, text2, text
按照约定,提交人:

函数substrCount由创建

由创建的函数拆分器


函数拆分\u str由

创建不可以,这是一个功能请求,不要将列表放入列中。如果你这样做了,那么把这样的任务留给应用程序。为什么是里克·詹姆斯?你的建议背后有什么原因吗?谢谢Dylan,我正在尝试运行查询,但结果对我来说不太好。选择FIELDATA,CONCAT_WS',,IFFIELDATA=SUBSTRING\u INDEX SUBSTRING_INDEX@str, '@', -5, ';', 1,如CATID=2的数据集的“%@%”,NULL,FieldData输出;输出与列值相同。请提供一些示例数据。我的错误。只需将@str替换为要在查询中使用的列名。应保留变量@tmp。如果你想只保留一个,如果要匹配一个@,请保留最后一个,即“-1”个。谢谢Walter。。以前从未做过函数。在运行时将函数放置在何处?您只需在数据库中运行一次创建脚本,然后像示例中一样使用:选择split_strf2,“;”,“@”,“,”,这很酷。在AWS RDS中创建和使用它是否也同样容易?是的,您可以在那里使用。此解决方案也很有效,但为了更容易推广,我使用了Dylan Su的答案。由于它已经过测试和使用,我选择了迪伦苏的一个作为公认的答案。但我真的很感激Walter_Ritzel的答案,它是通用的,可以在各地使用。我最终会使用这个解决方案。
text1, text2, text