mysql - 仅基于特定分隔符拆分字符串
问题描述
我正在尝试拆分一个字段(在某个分隔符';'处)并将结果插入表中。最多为 5 个由 ';' 分隔的子字符串 . 最多只有5个水果。仅给定水果列,如何拆分字符串以获取单独的水果。如果水果少于 5 个,剩余的列将返回 NA。
水果 | 水果1 | 水果2 | 水果3 | 水果4 | 水果5 |
---|---|---|---|---|---|
苹果; 橙; 香蕉 | 苹果 | 橙 | 香蕉 | -无效的- | -无效的- |
苹果; 橙; 菠萝; 火龙果; 香蕉 | 苹果 | 橙 | 菠萝 | 火龙果 | 香蕉 |
梨/葡萄;橙; 香蕉; 草莓 | 梨/葡萄 | 橙 | 香蕉 | 草莓 | -无效的- |
苹果; 蓝莓; 猕猴桃/柠檬 | 苹果 | 蓝莓 | 猕猴桃/柠檬 | -无效的- | -无效的- |
我第一次创建了新列并将其全部设置为空。我已经尝试了以下代码,但它不起作用,如果水果比列少,剩余的列将只取最后一个水果的值而不是 null。
SELECT
fruits,
SUBSTRING_INDEX(fruits, ';', 1) AS 'fruit1',
CASE
WHEN LOCATE(';', fruits, LENGTH(fruit1)+1) = 0 THEN NULL
ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(fruits, ';', 2), ';', -1)
END AS 'fruit2',
CASE
WHEN LOCATE(';', fruits, LENGTH(fruit1)+LENGTH(fruit2)+1) = 0 THEN NULL
WHEN LOCATE(';', fruits, (LOCATE(';', fruits, LENGTH(fruit1)) + 2)) = 0 THEN NULL
ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(fruits, ';', 3), ';', -1)
END AS 'fruit3',
CASE
WHEN LOCATE(';', fruits, LENGTH(fruit1) + LENGTH(fruit2) + LENGTH(fruit3) + 3) = 0 THEN NULL
WHEN LOCATE(';', fruits, (LOCATE(';', fruits, LENGTH(fruit1) + LENGTH(fruit2) + LENGTH(fruit3)+2) + 1)) = 0 THEN NULL
ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(fruits, ';', 4), ';', -1)
END AS 'fruit4'
FROM TABLENAME;
是否有更多信息可以拆分字符串?
解决方案
在 MySQL 5.7 和 8.0 中,现在支持 JSON 函数。你可以做一些字符串操作来改变它:
apple; orange; banana
进入这个:
["apple", "orange", "banana"]
然后使用 JSON 函数按位置提取特定的数组元素。
mysql> set @s = 'apple; orange; banana';
mysql> select cast(concat('["', replace(@s, '; ', '","'), '"]') as json) as array;
+-------------------------------+
| array |
+-------------------------------+
| ["apple", "orange", "banana"] |
+-------------------------------+
mysql> select json_unquote(json_extract(
cast(concat('["', replace(@s, '; ', '","'), '"]') as json),
'$[1]')) as element;
+---------+
| element |
+---------+
| orange |
+---------+
然后你可以提取'$[2]'
或'$[3]'
或任何其他元素。您可以使用->>
提取和取消引用的快捷方式。
SELECT
fruits,
fruits->>'$[0]' AS `fruit1`,
fruits->>'$[1]' AS `fruit2`,
fruits->>'$[2]' AS `fruit3`,
fruits->>'$[3]' AS `fruit4`
FROM (
SELECT CAST(CONCAT('["', REPLACE(fruits, '; ', '","'), '"]')) AS fruits
FROM TABLENAME
) AS f;
您可能会考虑将列表存储为 JSON 列,而不是当前以分号分隔的字符串格式。
推荐阅读
- python - 如何获取TensorFlow模型中输出节点的名称
- json - 根据属性反序列化两个不同的对象
- python - 从包含 dict 的 pandas 列中提取有用信息
- amazon-web-services - EC2 - 添加第二个接口和 pPrivat IP 导致没有链接
- javascript - WebGL 警告:texImage:跨域元素需要 CORS
- c# - 尝试使用数组输入 10 个数字,然后在每次输出后将它们写出来
- c# - NuGet 对新下载的包返回“包完整性检查”
- javascript - 无法在 Dynatrace 中执行 Javascript 正则表达式
- elasticsearch - 全文搜索引擎和安全性
- sql-server - 需要帮助理解在多对多表之间建立关系的正确方法