繁体   English   中英

如何在MySQL的字符串的第二个大写字母前插入空格?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM