MySQL字符串由逗号运算符分隔

时间:2016-05-09 14:36:31

标签: mysql stored-procedures stored-functions

我有字符串asdasdwdfef,rgrgtggt,weef,我希望输出如表格所示,如下所示

id      decription
1       asdasdwdfef
2       rgrgtggt
3       weef

为此,我创建了一个程序 这是我的程序

DELIMITER ;;
CREATE Procedure Split(_RowData text, _Delimeter text)
BEGIN
    DECLARE _Iterator INT default 1;
    DECLARE _FoundIndex INT;
    DECLARE _Data varchar(255);
    SET _FoundIndex = LOCATE(_Delimeter,_RowData);
    DROP TABLE IF EXISTS _RtnValue;
    CREATE temporary TABLE _RtnValue(ID INT AUTO_INCREMENT NOT NULL, description text, primary key(ID));
    WHILE _FoundIndex > 1 DO
        INSERT INTO _RtnValue (description)
        SELECT
        _Data = LTRIM(RTRIM(SUBSTRING(_RowData, 1, _FoundIndex - 1)));
        set _RowData = SUBSTRING(_RowData, _FoundIndex + LENGTH(_Delimeter) / 2, LENGTH(_RowData));
        SET _Iterator = _Iterator + 1;
        SET _FoundIndex = LOCATE(_Delimeter, _RowData);
    END WHILE;
    INSERT INTO _RtnValue(description) SELECT _Data = LTRIM(RTRIM(_RowData));
    select * from _RtnValue;
END

但是当我使用以下命令执行它时

call Split('asdasdwdfef,rgrgtggt,weef', ',');

它给了我以下输出:

id      decription
1       NULL
2       NULL
3       NULL

请告诉我如何解决此问题。 我正在使用MySQL。

2 个答案:

答案 0 :(得分:2)

我得到了答案

首先创建新功能

CREATE FUNCTION SPLIT_STR(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, '');

然后创建存储过程

DELIMITER ;;
CREATE PROCEDURE Split(in fullstr varchar(255))
BEGIN
    DECLARE a INT Default 0 ;
    DECLARE str VARCHAR(255);

    DROP TABLE IF EXISTS my_temp_table;
    CREATE temporary TABLE my_temp_table(ID INT AUTO_INCREMENT NOT NULL, description text, primary key(ID));

    simple_loop: LOOP
        SET a=a+1;
        SET str=SPLIT_STR(fullstr,",",a);
        IF str='' THEN
            LEAVE simple_loop;
        END IF;
        #Do Inserts into temp table here with str going into the row
        insert into my_temp_table (description) values (str);
   END LOOP simple_loop;
   select * from my_temp_table;
END

之后当我通过call Split('asas,d,sddf,dfd');给它打电话时,它给了我想要的输出。

对于每一个建议都是Thanx。

答案 1 :(得分:1)

要求:将“分隔”列拆分为行(表格)。

为什么呢?您可以使用所有SQL Aggregate函数来处理行。

Working SQLFiddle

使用此代码的相关问题:

我选择使用:

  • 整数表(integersequence)当'内部连接'或'交叉连接'(相同的东西)到另一个表时,将生成肯定具有从1开始的唯一序列号的行。这只是使用需要做什么RDBMS引擎。

  • 为什么是整数表?:它很小,会被加载到缓存中。这很容易理解。

  • 而不是在查询中包含大量代码,这些代码模糊了它实际执行的操作。我使用完成一项工作的功能。它简化了主查询,可以单独测试和检查。我现在只关心易于维护和理解。

这里的例子是一个字符串。但是,它可以很容易地扩展到各种大小的分隔字符串表。加入integersequence时,“交叉连接”将创建索引的所有可能选项(我真的需要使用另一个名称: - /)。

所以,查询:

SET @StrToParse = "asdasdwdfef,rgrgtggt,weef";

/* example */
select integerseries.id,
       count_in_set(@StrToParse, ','),
       value_in_set(@StrToParse, ',', integerseries.id)
from integerseries
where integerseries.id <= count_in_set(@StrToParse, ',');

输出:

PositionOfString, CountOfCommaDelimitedStrings, StringAtThatPosition 

1                 3                             asdasdwdfef
2                 3                             rgrgtggt
3                 3                             weef

现在,我们如何获得这些价值观:

我选择使用两个功能:

这些名称与mysql函数'FIND_IN_SET'

相关

1)COUNT_IN_SET函数:返回列中character delimited items的计数。

CREATE FUNCTION `COUNT_IN_SET`(haystack VARCHAR(1024), 
                               delim CHAR(1)
                               ) RETURNS INTEGER
BEGIN
      RETURN CHAR_LENGTH(haystack) - CHAR_LENGTH( REPLACE(haystack, delim, '')) + 1;
END$$

2)VALUE_IN_SET函数:将delimited list视为one based array并返回给定'索引'处的值。

CREATE FUNCTION `VALUE_IN_SET`(haystack VARCHAR(1024), 
                               delim CHAR(1), 
                               which INTEGER
                               ) RETURNS VARCHAR(255) CHARSET utf8 COLLATE utf8_unicode_ci
BEGIN
      RETURN  SUBSTRING_INDEX(SUBSTRING_INDEX(haystack, delim, which),
                     delim,
                     -1);
END$$

interseries表 - 见(Tally表)

CREATE TABLE `integerseries` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=500 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

/*Data for the table `integerseries` */

insert  into `integerseries`(`id`) values (1);
insert  into `integerseries`(`id`) values (2);
insert  into `integerseries`(`id`) values (3);
insert  into `integerseries`(`id`) values (4);
insert  into `integerseries`(`id`) values (5);
insert  into `integerseries`(`id`) values (6);
insert  into `integerseries`(`id`) values (7);
insert  into `integerseries`(`id`) values (8);
insert  into `integerseries`(`id`) values (9);
insert  into `integerseries`(`id`) values (10);