正規表現を使用して、カンマ区切りの文字列を MySQL の一時テーブルに解析できますか?
'1|2|5|6' into temp table with 4 rows.
これはCan Mysql Split a column?とほぼ同じ質問です。
MySQL には文字列分割機能がないため、回避策を講じる必要があります。上記の回答ページにリストされている方法のいずれかを使用してデータを分割すると、データに対して何でもできます。
そのカスタム関数をループして、空が返されたときに中断することができます。いくつかの構文を再生して学習する必要があります (少なくとも私はそうする必要があります)。ただし、mysql の FOR ループの構文は次のとおりです: http://www.roseindia .net/sql/mysql-example/for.shtml
以下の関数で位置をインクリメントして、それを反復できます。
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, '');
(クレジット: https://blog.fedecarg.com/2009/02/22/mysql-split-string-function/ )
一致が見つからない場合は '' を返す必要があるため、一致が見つからない場合はループを中断します。これにより、分割された文字列に対して mysql のみを解析し、挿入クエリを一時テーブルに実行できます。しかし、その種の作業にphpのようなスクリプト言語を使用しないのはなぜですか? :(
ループ構文のコード:
DELIMITER $$
CREATE PROCEDURE ABC(fullstr)
BEGIN
DECLARE a INT Default 0 ;
DECLARE str VARCHAR(255);
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 values (str);
END LOOP simple_loop;
END $$
DELIMITER $$
CREATE PROCEDURE SPLIT_VALUE_STRING()
BEGIN
SET @String = '1,22,333,444,5555,66666,777777';
SET @Occurrences = LENGTH(@String) - LENGTH(REPLACE(@String, ',', ''));
myloop: WHILE (@Occurrences > 0)
DO
SET @myValue = SUBSTRING_INDEX(@String, ',', 1);
IF (@myValue != '') THEN
/* my code... */
ELSE
LEAVE myloop;
END IF;
SET @Occurrences = LENGTH(@String) - LENGTH(REPLACE(@String, ',', ''));
IF (@occurrences = 0) THEN
LEAVE myloop;
END IF;
SET @String = SUBSTRING(@String,LENGTH(SUBSTRING_INDEX(@String, ',', 1))+2);
END WHILE;
END $$
テーブルの値がない場合などのために、私はこれを行いました:
select *
from(
select c, SUBSTRING_INDEX(SUBSTRING_INDEX('1|2|5|6', '|', c+1), '|', -1) as name
from(
SELECT (TWO_1.SeqValue + TWO_2.SeqValue + TWO_4.SeqValue + TWO_8.SeqValue + TWO_16.SeqValue + TWO_32.SeqValue) c
FROM (
SELECT 0 SeqValue UNION ALL SELECT 1 SeqValue) TWO_1
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 2 SeqValue) TWO_2
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 4 SeqValue) TWO_4
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 8 SeqValue) TWO_8
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 16 SeqValue) TWO_16
CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 32 SeqValue) TWO_32
) as b
WHERE c <= (CHAR_LENGTH('1|2|5|6') - CHAR_LENGTH(REPLACE('1|2|5|6', '|', '')))
) as a;
最良の答えではないかもしれませんが、関数や手順の助けがなくても機能し、追加のテーブルなどもありません。
MySQL では正規表現を使用して複雑な検索のパターンを指定できますが、文字列を解析することはできません。
ただし、REPLACE と CONCATENATE を使用して INSERT クエリを作成し、データを一時テーブルに保存できます。
分割しようとしているテキストにマルチバイト文字が含まれている場合、LENGTH が正しく計算されないため、このアプローチは失敗します。このような場合、LENGTH の代わりに CHAR_LENGTH を使用した次のバージョンが機能します。
CREATE DEFINER=`root`@`localhost` FUNCTION `strSplit`(
`src` MEDIUMTEXT CHARACTER SET utf8,
`delim` VARCHAR(12),
`pos` INTEGER
)
RETURNS mediumtext
LANGUAGE SQL
NOT DETERMINISTIC
CONTAINS SQL
SQL SECURITY DEFINER
COMMENT ''
BEGIN
DECLARE output MEDIUMTEXT CHARACTER SET utf8;
SET output = REPLACE(SUBSTRING(SUBSTRING_INDEX(src, delim, pos) ,
CHAR_LENGTH(SUBSTRING_INDEX(src, delim, pos - 1)) + 1) , delim , '');
IF output = '' THEN SET output = null; END IF;
RETURN output;
END
参照: http://www.shakedos.com/2011/Nov/23/mysql-split-string-function-fix-split_str.html