MySQL 字符串用逗号分隔
MySQL String separation by comma operator
我有字符串 asdasdwdfef,rgrgtggt,weef
并且我想要输出 table 格式,如下所示
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.
要求:将'delimited'列拆分为行(table)。
为什么?您可以使用所有 SQL 聚合函数来处理行。
使用此代码的相关问题:
我选择使用:
table 的整数(integersequence),当 'inner joined' 或 'cross joined' (相同的东西)到另一个 table 时将生成确定的行有一个从 1 开始的唯一序列号。这只是使用 RDBMS 引擎需要做的事情。
为什么 table 整数?:它很小,会被加载到缓存中。很容易理解。
而不是在查询中使用大量代码来掩盖它的实际作用。我使用完成一项工作的功能。它简化了主查询,可以单独测试和检查。在这一点上,我只关心易于维护和理解。
这里的例子是一个字符串。但是,它可以很容易地扩展为 table 各种大小的分隔字符串。 'cross join' 将在加入 integersequence
时创建从 1 开始的所有可能的索引选项(我真的需要使用另一个名称:-/)。
所以,查询:
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
函数:returns 列中 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
和 returns 给定 'index'.[=26= 处的值]
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$$
中间系列 table - 参见 (Tally tables)
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);
我得到了答案
首先创建新函数
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');
调用它时,它会给我想要的输出。
谢谢大家的建议。
我有字符串 asdasdwdfef,rgrgtggt,weef
并且我想要输出 table 格式,如下所示
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.
要求:将'delimited'列拆分为行(table)。
为什么?您可以使用所有 SQL 聚合函数来处理行。
使用此代码的相关问题:
我选择使用:
table 的整数(integersequence),当 'inner joined' 或 'cross joined' (相同的东西)到另一个 table 时将生成确定的行有一个从 1 开始的唯一序列号。这只是使用 RDBMS 引擎需要做的事情。
为什么 table 整数?:它很小,会被加载到缓存中。很容易理解。
而不是在查询中使用大量代码来掩盖它的实际作用。我使用完成一项工作的功能。它简化了主查询,可以单独测试和检查。在这一点上,我只关心易于维护和理解。
这里的例子是一个字符串。但是,它可以很容易地扩展为 table 各种大小的分隔字符串。 'cross join' 将在加入 integersequence
时创建从 1 开始的所有可能的索引选项(我真的需要使用另一个名称:-/)。
所以,查询:
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
函数:returns 列中 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
和 returns 给定 'index'.[=26= 处的值]
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$$
中间系列 table - 参见 (Tally tables)
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);
我得到了答案
首先创建新函数
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');
调用它时,它会给我想要的输出。
谢谢大家的建议。