Здесь приведен общий запрос для всех версий 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<br>
) AS names
Почему нет LIMIT
?LIMIT
медленно при использовании с большими числами смещения, такими как LIMIT 1000000, 1000
.MySQL необходимо извлечь 1001000 записей и снова удалить 1000000 записей из временной таблицы (диск в худшем случае)
. demo
Отредактировано
для меня все это похоже на черную магию!Это почти идеально - попробуйте названия «AlexLafferty» или «LaurenAnderson».Может быть, одна ошибка или что-то на А?Спасибо за вашу помощь!
После обзора я заметил, что использование LOCATE(..)
в INSERT(..)
довольно избыточно и может быть удалено для правильной работы.
Так что патч
SELECT
names.name
, INSERT (
names.name
, number_generator.number
, 1
, CONCAT(' ', SUBSTRING(names.name, number_generator.number, 1))
) AS changed_name
см. демо