Есть ли простой способ преобразования данных MySQL в Title Case?
У меня есть таблица MySQL, в которой все данные в одном столбце были введены в UPPERCASE, но мне нужно преобразовать их в Title Case, с признанием «маленьких слов», сродни сценарию Case of Fireing Fireball .
Я нашел это отличное решение для преобразования строк в нижний регистр, но функция Title Case, похоже, была исключена из моей версии MySQL. Есть ли элегантный способ сделать это?
- Почему оцененные ряды очень сильно отличаются по результатам phpmyadmin?
- Восстановить структуру таблицы из файлов frm и ibd
- Ошибка? # 1146 - Таблица "xxx.xxxxx" не существует
- MySQL: невозможно создать таблицу (errno: 150)
- MySQL: нет в GROUP BY
- Подзапросы с EXISTS против IN - MySQL
- Как получить доступ к удаленному серверу с помощью локального клиента phpMyAdmin?
- Никакое соединение не может быть сделано, потому что целевая машина активно отказалась от него
- PHPMyAdmin Default login password
- phpMyAdmin бросает # 2002 не может войти на сервер mysql phpmyadmin
- Ошибка удаления базы данных (не может rmdir '.test \', errno: 17)
- SQL: удаление таблиц с префиксом
- Ошибка XAMPP phpMyAdmin с # 2002
редактировать
Эврика! Буквально моя первая функция SQL. Гарантия не предоставляется. Резервное копирование данных перед использованием. 🙂
Сначала определите следующую функцию:
DROP FUNCTION IF EXISTS lowerword; SET GLOBAL log_bin_trust_function_creators=TRUE; DELIMITER | CREATE FUNCTION lowerword( str VARCHAR(128), word VARCHAR(5) ) RETURNS VARCHAR(128) DETERMINISTIC BEGIN DECLARE i INT DEFAULT 1; DECLARE loc INT; SET loc = LOCATE(CONCAT(word,' '), str, 2); IF loc > 1 THEN WHILE i <= LENGTH (str) AND loc <> 0 DO SET str = INSERT(str,loc,LENGTH(word),LCASE(word)); SET i = loc+LENGTH(word); SET loc = LOCATE(CONCAT(word,' '), str, i); END WHILE; END IF; RETURN str; END; | DELIMITER ;
Это уменьшит все вхождения слова в str.
Затем определите эту модифицированную правильную функцию:
DROP FUNCTION IF EXISTS tcase; SET GLOBAL log_bin_trust_function_creators=TRUE; DELIMITER | CREATE FUNCTION tcase( str VARCHAR(128) ) RETURNS VARCHAR(128) DETERMINISTIC BEGIN DECLARE c CHAR(1); DECLARE s VARCHAR(128); DECLARE i INT DEFAULT 1; DECLARE bool INT DEFAULT 1; DECLARE punct CHAR(17) DEFAULT ' ()[]{},.-_!@;:?/'; SET s = LCASE( str ); WHILE i <= LENGTH( str ) DO BEGIN SET c = SUBSTRING( s, i, 1 ); IF LOCATE( c, punct ) > 0 THEN SET bool = 1; ELSEIF bool=1 THEN BEGIN IF c >= 'a' AND c <= 'z' THEN BEGIN SET s = CONCAT(LEFT(s,i-1),UCASE(c),SUBSTRING(s,i+1)); SET bool = 0; END; ELSEIF c >= '0' AND c <= '9' THEN SET bool = 0; END IF; END; END IF; SET i = i+1; END; END WHILE; SET s = lowerword(s, 'A'); SET s = lowerword(s, 'An'); SET s = lowerword(s, 'And'); SET s = lowerword(s, 'As'); SET s = lowerword(s, 'At'); SET s = lowerword(s, 'But'); SET s = lowerword(s, 'By'); SET s = lowerword(s, 'For'); SET s = lowerword(s, 'If'); SET s = lowerword(s, 'In'); SET s = lowerword(s, 'Of'); SET s = lowerword(s, 'On'); SET s = lowerword(s, 'Or'); SET s = lowerword(s, 'The'); SET s = lowerword(s, 'To'); SET s = lowerword(s, 'Via'); RETURN s; END; | DELIMITER ;
Применение
Убедитесь, что он работает, как ожидалось:
SELECT tcase(title) FROM table;
Используй это:
UPDATE table SET title = tcase(title);
Источник: http://www.artfulsoftware.com/infotree/queries.php?&bw=1070#122
umm что-то вроде этого может работать
UPDATE table_name SET `col_name`= CONCAT( UPPER( SUBSTRING( `col_name`, 1, 1 ) ) , LOWER( SUBSTRING( `col_name` FROM 2 ) ) );
Если вам нужно бросить специальные акронимы и другие настраиваемые шаблоны заглавной буквы в микс, я обобщил ответ hobodave:
DELIMITER | CREATE FUNCTION replaceword( str VARCHAR(128), word VARCHAR(128) ) RETURNS VARCHAR(128) DETERMINISTIC BEGIN DECLARE loc INT; DECLARE punct CHAR(27) DEFAULT ' ()[]{},.-_!@;:?/''"#$%^&*<>'; DECLARE lowerWord VARCHAR(128); DECLARE lowerStr VARCHAR(128); IF LENGTH(word) = 0 THEN RETURN str; END IF; SET lowerWord = LOWER(word); SET lowerStr = LOWER(str); SET loc = LOCATE(lowerWord, lowerStr, 1); WHILE loc > 0 DO IF loc = 1 OR LOCATE(SUBSTRING(str, loc-1, 1), punct) > 0 THEN IF loc+LENGTH(word) > LENGTH(str) OR LOCATE(SUBSTRING(str, loc+LENGTH(word), 1), punct) > 0 THEN SET str = INSERT(str,loc,LENGTH(word),word); END IF; END IF; SET loc = LOCATE(lowerWord, lowerStr, loc+LENGTH(word)); END WHILE; RETURN str; END; | DELIMITER ; DELIMITER | CREATE FUNCTION tcase( str VARCHAR(128) ) RETURNS VARCHAR(128) DETERMINISTIC BEGIN DECLARE c CHAR(1); DECLARE s VARCHAR(128); DECLARE i INT DEFAULT 1; DECLARE bool INT DEFAULT 1; DECLARE punct CHAR(27) DEFAULT ' ()[]{},.-_!@;:?/''"#$%^&*<>'; SET s = LCASE( str ); WHILE i <= LENGTH( str ) DO BEGIN SET c = SUBSTRING( s, i, 1 ); IF LOCATE( c, punct ) > 0 THEN SET bool = 1; ELSEIF bool=1 THEN BEGIN IF c >= 'a' AND c <= 'z' THEN BEGIN SET s = CONCAT(LEFT(s,i-1),UCASE(c),SUBSTRING(s,i+1)); SET bool = 0; END; ELSEIF c >= '0' AND c <= '9' THEN SET bool = 0; END IF; END; END IF; SET i = i+1; END; END WHILE; SET s = replaceword(s, 'a'); SET s = replaceword(s, 'an'); SET s = replaceword(s, 'and'); SET s = replaceword(s, 'as'); SET s = replaceword(s, 'at'); SET s = replaceword(s, 'but'); SET s = replaceword(s, 'by'); SET s = replaceword(s, 'for'); SET s = replaceword(s, 'if'); SET s = replaceword(s, 'in'); SET s = replaceword(s, 'n'); SET s = replaceword(s, 'of'); SET s = replaceword(s, 'on'); SET s = replaceword(s, 'or'); SET s = replaceword(s, 'the'); SET s = replaceword(s, 'to'); SET s = replaceword(s, 'via'); SET s = replaceword(s, 'RSS'); SET s = replaceword(s, 'URL'); SET s = replaceword(s, 'PHP'); SET s = replaceword(s, 'SQL'); SET s = replaceword(s, 'OPML'); SET s = replaceword(s, 'DHTML'); SET s = replaceword(s, 'CSV'); SET s = replaceword(s, 'iCal'); SET s = replaceword(s, 'XML'); SET s = replaceword(s, 'PDF'); SET c = SUBSTRING( s, 1, 1 ); IF c >= 'a' AND c <= 'z' THEN SET s = CONCAT(UCASE(c),SUBSTRING(s,2)); END IF; RETURN s; END; | DELIMITER ;
По сути, он состоит из функции замены слова без учета регистра и функции для заглавной буквы первой буквы каждого слова и выполнения некоторых преобразований для определенных слов.
Надеюсь, что это поможет кому-то.
Мое решение для простого правильного случая:
CREATE FUNCTION `proper_case`(str varchar(128)) RETURNS varchar(128) BEGIN DECLARE n, pos INT DEFAULT 1; DECLARE sub, proper VARCHAR(128) DEFAULT ''; if length(trim(str)) > 0 then WHILE pos > 0 DO set pos = locate(' ',trim(str),n); if pos = 0 then set sub = lower(trim(substr(trim(str),n))); else set sub = lower(trim(substr(trim(str),n,pos-n))); end if; set proper = concat_ws(' ', proper, concat(upper(left(sub,1)),substr(sub,2))); set n = pos + 1; END WHILE; end if; RETURN trim(proper); END
Используйте его как:
SELECT proper_case("JOHN DOE");
Вывод:
John Doe
Я использовал что-то вроде этого
UPDATE `tablename` SET `fieldname` = CONCAT(UCASE(SUBSTRING(`fieldname`,1,1)),'', LCASE(SUBSTRING(`fieldname`,2,LENGTH(`fieldname`))))
Примечание. Это преобразует только первый символ в верхний регистр. и остальное значение в нижнем регистре.
вы можете сделать это с помощью concat (), substring () и length (), но я могу видеть, что он работает только для одного слова. Есть ли конкретная причина, по которой вы не можете сделать это в коде приложения, а не в mysql?
Woo! Мне вообще не нравится SQL; Вот метод, который работал для меня:
- Экспортируйте таблицу в виде текстового файла в формате .sql.
- Откройте файл в Textmate (который мне уже пригодится).
- Выберите строки с данными UPPERCASE.
- Выберите «Конвертировать» в меню «Текст» и выберите «В раздел« Теневая запись ».
-
Найдите и замените каждый экземпляр:
INSERT INTO `Table` (`Col1`, `Col2`, `Etc`, ...) VALUES
с правильными строчными значениями.
- Импортируйте таблицу обратно в базу данных.
- Использовать
UPDATE table SET colname=LOWER(colname);
для сброса строчных значений для столбцов, которые должны быть строчными.
Причина, по которой я не пыталась использовать Textmate, заключалась в том, что я не мог понять, как преобразовать один столбец в заголовок, без разрушения других данных, но этот метод, похоже, работает. Спасибо за ваше руководство и поддержку!
Это работает для меня.
UPDATE `suburbs` SET title2 = CONCAT_WS(' ', CONCAT(UPPER(LEFT(SUBSTRING_INDEX(title, ' ',1),1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',1),2))), CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',2),LENGTH(SUBSTRING_INDEX(title, ' ',1)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',2),3 + LENGTH(SUBSTRING_INDEX(title, ' ',1))))), CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',3),LENGTH(SUBSTRING_INDEX(title, ' ',2)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',3),3 + LENGTH(SUBSTRING_INDEX(title, ' ',2))))), CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',4),LENGTH(SUBSTRING_INDEX(title, ' ',3)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',4),3 + LENGTH(SUBSTRING_INDEX(title, ' ',3))))), CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',5),LENGTH(SUBSTRING_INDEX(title, ' ',4)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',5),3 + LENGTH(SUBSTRING_INDEX(title, ' ',4))))), CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',6),LENGTH(SUBSTRING_INDEX(title, ' ',5)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',6),3 + LENGTH(SUBSTRING_INDEX(title, ' ',5))))), CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',7),LENGTH(SUBSTRING_INDEX(title, ' ',6)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',7),3 + LENGTH(SUBSTRING_INDEX(title, ' ',6))))), CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',8),LENGTH(SUBSTRING_INDEX(title, ' ',7)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',8),3 + LENGTH(SUBSTRING_INDEX(title, ' ',7))))), CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',9),LENGTH(SUBSTRING_INDEX(title, ' ',8)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',9),3 + LENGTH(SUBSTRING_INDEX(title, ' ',8))))), CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',10),LENGTH(SUBSTRING_INDEX(title, ' ',9)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',10),3 + LENGTH(SUBSTRING_INDEX(title, ' ',9))))), CONCAT(UPPER(MID(SUBSTRING_INDEX(title, ' ',11),LENGTH(SUBSTRING_INDEX(title, ' ',10)) + 2, 1)), LOWER(MID(SUBSTRING_INDEX(title, ' ',11),3 + LENGTH(SUBSTRING_INDEX(title, ' ',10)))))) WHERE 1
Это работает для меня. В моем SQL 5.0
DELIMITER | CREATE FUNCTION CamelCase(str VARCHAR(8000)) RETURNS VARCHAR(8000) BEGIN DECLARE result VARCHAR(8000); SET str = CONCAT(' ',str,' '); SET result = ''; WHILE LENGTH(str) > 1 DO SET str = SUBSTR(str,INSTR(str,' ')+1,LENGTH(str)); SET result = CONCAT(result,UPPER(LEFT(str,1)), LOWER(SUBSTR(str,2,INSTR(str,' ') - 1)) ) ; SET str = SUBSTR(str,INSTR(str,' '),LENGTH(str)); END WHILE; RETURN result; END | DELIMITER ;
Окончательный вариант поиска такой функции содержится в документации .
К сожалению, у вас есть функции LOWER () и UPPER (), но нет Title Case. Лучше всего было бы объявить свою собственную функцию, которая разбивается на пробелы, игнорирует ваши маленькие слова и делает UPPER по первому символу каждого оставшегося слова.
Ответ будет зависеть от того, какой тип данных находится в столбце, то есть имена людей, имена мест, названия книг и т. Д. Если вы ищете решение SQL, я бы сделал это в нескольких обновлениях, например:
- Исходная строка: «УБИРАТЬ КОРОБКУ»
- Преобразовать в начальные колпачки: «Убить пересмешника»
- Преобразуйте маленькие слова в нижний регистр, если они не запустили строку: «Убить пересмешника»