Mysql 使用“;”从行到列分隔器
Mysql Row to Column with ';' separator
我的 Mariadb 10.1
上有一个 table(目录)
id value
1 one ; two ; one
2 two ; three ; one
3 four ; five
4 one
5 four ; one
我如何计算和分组目录 table 上的值,就像下面的 table 一样。
result count
one 5
two 2
three 1
four 2
five 1
或这个table
id value
1 one
1 two
1 one
2 two
2 three
2 one
3 four
3 five
4 one
5 four
5 one
参考自link http://www.marcogoncalves.com/2011/03/mysql-split-column-string-into-rows/
假设您将 table 命名为 table1
,其中包含两列 id
和 value
,并且 value
列包含逗号分隔值。
修改后的程序:
CREATE PROCEDURE `explode_table`(bound VARCHAR(255))
BEGIN
DECLARE id INT DEFAULT 0;
DECLARE value TEXT;
DECLARE occurance INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
DECLARE splitted_value varchar(25);
DECLARE done INT DEFAULT 0;
DECLARE cur1 CURSOR FOR SELECT table1.id, table1.value
FROM table1
WHERE table1.value != '';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
DROP TEMPORARY TABLE IF EXISTS table2;
CREATE TEMPORARY TABLE table2(
`id` INT NOT NULL,
`value` VARCHAR(56) NOT NULL
) engine=memory;
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO id, value;
IF done THEN
LEAVE read_loop;
END IF;
SET occurance = (SELECT LENGTH(value)
- LENGTH(REPLACE(value, bound, ''))
+1);
SET i=1;
WHILE i <= occurance DO
SET splitted_value =
trim((SELECT REPLACE(SUBSTRING(SUBSTRING_INDEX(value, bound, i),
LENGTH(SUBSTRING_INDEX(value, bound, i - 1)) + 1), ';', '')));
INSERT INTO table2 VALUES (id, splitted_value);
SET i = i + 1;
END WHILE;
END LOOP;
CLOSE cur1;
SELECT * FROM table2;
END
一种简单的 SQL 方法,最多可处理 100 个分割定界值(如有必要,可轻松扩展以处理更多):-
SELECT result, COUNT(id)
FROM
(
SELECT id, SUBSTRING_INDEX(SUBSTRING_INDEX(value, ' ; ', tens.anum * 10 + units.anum + 1), ' ; ', -1) AS result
FROM Catalogs
CROSS JOIN
(SELECT 1 AS anum UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0) units
CROSS JOIN
(SELECT 1 AS anum UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0) tens
WHERE LENGTH(value) - LENGTH(REPLACE(value, ';', '')) >= ( tens.anum * 10 + units.anum)
) sub0
GROUP BY result
我的 Mariadb 10.1
上有一个 table(目录)id value
1 one ; two ; one
2 two ; three ; one
3 four ; five
4 one
5 four ; one
我如何计算和分组目录 table 上的值,就像下面的 table 一样。
result count
one 5
two 2
three 1
four 2
five 1
或这个table
id value
1 one
1 two
1 one
2 two
2 three
2 one
3 four
3 five
4 one
5 four
5 one
参考自link http://www.marcogoncalves.com/2011/03/mysql-split-column-string-into-rows/
假设您将 table 命名为 table1
,其中包含两列 id
和 value
,并且 value
列包含逗号分隔值。
修改后的程序:
CREATE PROCEDURE `explode_table`(bound VARCHAR(255))
BEGIN
DECLARE id INT DEFAULT 0;
DECLARE value TEXT;
DECLARE occurance INT DEFAULT 0;
DECLARE i INT DEFAULT 0;
DECLARE splitted_value varchar(25);
DECLARE done INT DEFAULT 0;
DECLARE cur1 CURSOR FOR SELECT table1.id, table1.value
FROM table1
WHERE table1.value != '';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
DROP TEMPORARY TABLE IF EXISTS table2;
CREATE TEMPORARY TABLE table2(
`id` INT NOT NULL,
`value` VARCHAR(56) NOT NULL
) engine=memory;
OPEN cur1;
read_loop: LOOP
FETCH cur1 INTO id, value;
IF done THEN
LEAVE read_loop;
END IF;
SET occurance = (SELECT LENGTH(value)
- LENGTH(REPLACE(value, bound, ''))
+1);
SET i=1;
WHILE i <= occurance DO
SET splitted_value =
trim((SELECT REPLACE(SUBSTRING(SUBSTRING_INDEX(value, bound, i),
LENGTH(SUBSTRING_INDEX(value, bound, i - 1)) + 1), ';', '')));
INSERT INTO table2 VALUES (id, splitted_value);
SET i = i + 1;
END WHILE;
END LOOP;
CLOSE cur1;
SELECT * FROM table2;
END
一种简单的 SQL 方法,最多可处理 100 个分割定界值(如有必要,可轻松扩展以处理更多):-
SELECT result, COUNT(id)
FROM
(
SELECT id, SUBSTRING_INDEX(SUBSTRING_INDEX(value, ' ; ', tens.anum * 10 + units.anum + 1), ' ; ', -1) AS result
FROM Catalogs
CROSS JOIN
(SELECT 1 AS anum UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0) units
CROSS JOIN
(SELECT 1 AS anum UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 0) tens
WHERE LENGTH(value) - LENGTH(REPLACE(value, ';', '')) >= ( tens.anum * 10 + units.anum)
) sub0
GROUP BY result