![](/img/trans.png)
[英]SQL : Multiple String Replace (Add a space in front of capital letter(s) starting with 2nd capital letter)
[英]How to insert a space before the 2nd capital letter of a string in MySQL?
我有来自第三方的一些数据,其中一列是姓和名的串联-但两者之间没有空格。 我的目标是在第二个大写字母之前插入一个空格,例如:
some_name
-------------
AdamPeterson
JohnSmith
StevenMulroy
会成为:
some_name
-------------
Adam Peterson
John Smith
Steven Mulroy
我知道这不是万无一失的,但这是我拥有的源数据所能获得的最好的结果。
我需要在SQL中而不是在Excel等中执行此操作-因为数据会在数据库级别定期刷新,然后由另一个系统处理,而无需首先导出。
任何帮助是极大的赞赏!
对于MySQL 8
SELECT REGEXP_REPLACE(CAST('JohnLexxxanon' as BINARY), '^([A-Z][a-z]+)([A-Z][a-z]+)$', '$1 $2');
对于MariaDb 10+
SELECT REGEXP_REPLACE(CAST('JohnLexxxanon' as BINARY), '^([A-Z][a-z]+)([A-Z][a-z]+)$', '\\1 \\2');
数据被强制转换为二进制以实现区分大小写。
这适用于MySql 8和MariaDb 10+
这是对所有MySQL 5.1+版本的常规查询,可以肯定它也将在MariaDB上运行。
一般想法是使用MySQL数字生成器将字符串拆分为“令牌”,并检查“ ASCII”范围(如果“令牌”为大写字母)
询问
SELECT
names.name
, INSERT (
names.name
, LOCATE(
SUBSTRING(names.name, number_generator.number, 1)
, names.name
)
, 1
, CONCAT(' ', SUBSTRING(names.name, number_generator.number, 1))
) AS changed_name
FROM (
SELECT
@row := @row + 1 AS number
FROM (
SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) row1
CROSS JOIN (
SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) row2
CROSS JOIN (
SELECT @row := 0
) init_user_params
) AS number_generator
CROSS JOIN
names
WHERE
number_generator.number > 1
AND
ASCII(SUBSTRING(names.name, number_generator.number, 1)) BETWEEN 65 AND 90
结果
| name | changed_name |
| ------------ | ------------- |
| AdamPeterson | Adam Peterson |
| JohnSmith | John Smith |
| StevenMulroy | Steven Mulroy |
观看演示
注意
此查询无法在具有数百万甚至数十亿条记录的(非常)大型表上很好地扩展,因为CROSS JOIN
或者您可以使用无表方法
CROSS JOIN ( SELECT 'AdamPeterson' AS name UNION SELECT 'JohnSmith' UNION SELECT 'StevenMulroy' ) AS names
看那个演示
或有大桌子时使用批处理
CROSS JOIN ( SELECT name FROM names WHERE id >= 1 AND id <= 2 ORDER BY names.id ASC
) AS names
为什么没有LIMIT
? 当将LIMIT 1000000, 1000
等大偏移量与LIMIT 1000000, 1000
一起使用时, LIMIT
会变慢。 MySQL需要从(在最坏情况下的磁盘)临时表中提取1001000条记录并再次删除1000000条记录
看那个演示
编辑
在我看来,这一切都像黑魔法! 这几乎是完美的-尝试使用名称“ AlexLafferty”或“ LaurenAnderson”。 也许是一个错误的bug或A上的某个东西? 感谢你的帮助!
经过审查后,我注意到在INSERT(..)
中使用LOCATE(..)
非常多余,可以将其删除以使其正常工作。
所以补丁是
SELECT
names.name
, INSERT (
names.name
, number_generator.number
, 1
, CONCAT(' ', SUBSTRING(names.name, number_generator.number, 1))
) AS changed_name
观看演示
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.