MySQL 쉼표 문자열을 임시 테이블로 분리
RegEx를 사용하여 MySQL에서 쉼표로 구분된 문자열을 임시 테이블로 구문 분석할 수 있습니까?
'1|2|5|6' into temp table with 4 rows.
이것은 Mysql이 칼럼을 분할할 수 있는가와 거의 같은 질문입니다.
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 $$
이것에 대한 좋은 해결책을 찾았습니다.
https://forums.mysql.com/read.php?10,635524,635529
피터 브래들리 덕분에
트릭: csv 문자열의 Group_Concat() 결과를 삽입...에 마사지합니다.값...문자열:
drop table if exists t;
create table t( txt text );
insert into t values('1,2,3,4,5,6,7,8,9');
drop temporary table if exists temp;
create temporary table temp( val char(255) );
set @sql = concat("insert into temp (val) values ('", replace(( select group_concat(distinct txt) as data from t), ",", "'),('"),"');");
prepare stmt1 from @sql;
execute stmt1;
select distinct(val) from temp;
+------+
| val |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
+------+
또한 id 목록에 테이블을 추가하고 싶다면 LIKE 연산자를 사용할 수 있습니다.블로그 포스트 URL에서 id 목록을 받아 쉼표로 시작하여 쉼표로 끝나는 목록으로 변환한 후 LIKE 연산자와 id 목록으로 관련 제품에 가입하는 솔루션이 있습니다.
SELECT b2.id blog_id, b2.id_list, p.id
FROM (
SELECT b.id,b.text,
CONCAT(
",",
REPLACE(
EXTRACTVALUE(b.text,'//a/@id')
, " ", ","
)
,","
) AS id_list
FROM blog b
) b2
LEFT JOIN production p ON b2.id_list LIKE CONCAT('%,',p.id,',%')
HAVING b2.id_list != ''
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;
최선의 답은 아니지만 기능 및 절차, 추가 테이블 등의 도움 없이 작동합니다.
select distinct
SUBSTRING_INDEX(SUBSTRING_INDEX('1,2,3,4', ',', numbers.n), ',', -1) name
from
(select @rownum := @rownum + 1 as n
from YourTable
cross join (select @rownum := 0) r
) numbers
order by
n
MySQL에서 정규식을 사용하여 복잡한 검색에 대한 패턴을 지정할 수 있으며 문자열을 구문 분석할 수 없습니다.
그러나 REFREENT 및 CONCATENATE의 도움으로 INSERT 쿼리를 구축하여 임시 테이블에 데이터를 저장할 수 있습니다.
오래된 질문을 부활시키는 것을 정말 좋아하기 때문에.
CREATE PROCEDURE `SPLIT_LIST_STR`(IN `INISTR` TEXT CHARSET utf8mb4, IN `ENDSTR` TEXT CHARSET utf8mb4, IN `INPUTSTR` TEXT CHARSET utf8mb4, IN `SEPARATR` TEXT CHARSET utf8mb4)
BEGIN
SET @I = 1;
SET @SEP = SEPARATR;
SET @INI = INISTR;
SET @END = ENDSTR;
SET @VARSTR = REPLACE(REPLACE(INPUTSTR, @INI, ''), @END, '');
SET @N = FORMAT((LENGTH(@VARSTR)-LENGTH(REPLACE(@VARSTR, @SEP, '')))/LENGTH(@SEP), 0)+1;
CREATE TEMPORARY TABLE IF NOT EXISTS temp_table(P1 TEXT NULL);
label1: LOOP
SET @TEMP = SUBSTRING_INDEX(@VARSTR, @SEP, 1);
insert into temp_table (`P1`) SELECT @TEMP;
SET @I = @I + 1;
SET @VARSTR = REPLACE(@VARSTR, CONCAT(@TEMP, @SEP), '');
IF @N >= @I THEN
ITERATE label1;
END IF;
LEAVE label1;
END LOOP label1;
SELECT * FROM temp_table;
END
생산되는 제품:
P1
1
2
3
4
사용시CALL SPLIT_LIST_STR('("', '")', '("1", "2", "3", "4")', '", "');
코드를 좀 더 정리하기 위해 나중에 불쑥 나타날지도 몰라요!건배!
분할하려는 텍스트에 멀티바이트 문자가 포함되어 있는 경우 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
언급URL : https://stackoverflow.com/questions/11835155/mysql-split-comma-separated-string-into-temp-table
'programing' 카테고리의 다른 글
절차에 대한 각 대안에 대한 MySQL (0) | 2023.10.10 |
---|---|
AngularJsngIf로 인해 지시문 내부의 요소를 찾을 수 없습니다. (0) | 2023.10.10 |
jQuery tract vs prop? (0) | 2023.10.10 |
자바스크립트 값이 "정수"인지 확인하시겠습니까? (0) | 2023.10.10 |
워드프레스 커스텀 숏코드 편집기 [백본JS & TinyMCE) (0) | 2023.10.10 |