Capitalize first letter of each word, in existing table

Viewed 89973

I have an existing table 'people_table', with a field full_name.

Many records have the 'full_name' field populated with incorrect casing. e.g. 'fred Jones' or 'fred jones' or 'Fred jones'.

I can find these errant entries with:

SELECT * FROM people_table WHERE full_name REGEXP BINARY '^[a-z]';

How can I capitalize the first letter of each word found? e.g. 'fred jones' becomes 'Fred Jones'.

14 Answers

Simply :

SELECT
CONCAT(UCASE(LEFT(firstname, 1)), LCASE(SUBSTRING(firstname, 2))) as firstname
FROM PEOPLE

No need for creating a function if it is a one timer. The below works just fine:

-- Capitalize first letter of each word in r.name field
SELECT TRIM(CONCAT(
   CONCAT(UPPER(SUBSTRING(cname1,1,1)),SUBSTRING(cname1,2)) , " ",
   CONCAT(UPPER(SUBSTRING(cname2,1,1)),SUBSTRING(cname2,2)) , " ",
   CONCAT(UPPER(SUBSTRING(cname3,1,1)),SUBSTRING(cname3,2))))
FROM (
   SELECT
     @num_spaces := 1 + LENGTH(c_name) - LENGTH(REPLACE(c_name, ' ', '')) AS 
     num_spaces,
     SUBSTRING_INDEX(CONVERT(c_name,CHAR), ' ', 1) AS cname1,
     IF(@num_spaces > 1, SUBSTRING_INDEX(SUBSTRING_INDEX(c_name, ' ', 2), ' ', -1), '') AS cname2,
     IF(@num_spaces > 2, SUBSTRING_INDEX(SUBSTRING_INDEX(c_name, ' ', 3), ' ', -1), '') AS cname3
     FROM (SELECT (CASE 
        WHEN UPPER(r.name)COLLATE latin1_general_cs =r.name THEN LOWER(TRIM(r.name))
        ELSE TRIM(r.name)
        END) AS c_name,r.name
        FROM table r) cr) ncr;

NOTE: The IF clause should be equal to or more than the value of @num_spaces. The current sql will take care of at max 3 words. You may add more if required.

firstly create a function

DROP FUNCTION IF EXISTS UC_FIRST;
CREATE FUNCTION UC_FIRST(oldWord VARCHAR(255)) RETURNS VARCHAR(255) 
RETURN CONCAT(UCASE(SUBSTRING(oldWord, 1, 1)),SUBSTRING(oldWord, 2));

and then use this query

UPDATE mytable SET thefield = UC_FIRST(thefield);

Answer from Eric Leroy is the most interesting answer here, but it misses two things:

  • Lower case in UC_FIRST function: if you want to uppercase the first letter for a word, it means that you also want the other letters to be lowercase. It works with a full lowercase entry, but if ever in entry you get mixed cases such as «wOrD», you would get «WOrD» when you want «Word».
  • Depending on the mysql version and configuration, you may need the deterministic key word in the function definition.

Here is the updated code to create the functions:

DROP FUNCTION IF EXISTS UC_FIRST;
CREATE FUNCTION UC_FIRST(oldWord VARCHAR(255)) RETURNS VARCHAR(255) DETERMINISTIC
RETURN CONCAT(UCASE(SUBSTRING(oldWord, 1, 1)),LCASE(SUBSTRING(oldWord, 2)));

DROP FUNCTION IF EXISTS UC_DELIMITER;
DELIMITER //
CREATE FUNCTION UC_DELIMITER(
   oldName VARCHAR(255), delim VARCHAR(1), trimSpaces BOOL
) 
  RETURNS VARCHAR(255) DETERMINISTIC
BEGIN
SET @oldString := oldName;
SET @newString := "";

tokenLoop: LOOP
    IF trimSpaces THEN SET @oldString := TRIM(BOTH " " FROM @oldString);          END IF;

SET @splitPoint := LOCATE(delim, @oldString);

IF @splitPoint = 0 THEN
  SET @newString := CONCAT(@newString, UC_FIRST(@oldString));
  LEAVE tokenLoop;
END IF;

   SET @newString := CONCAT(@newString, UC_FIRST(SUBSTRING(@oldString, 1, @splitPoint)));
   SET @oldString := SUBSTRING(@oldString, @splitPoint+1);
END LOOP tokenLoop;

RETURN @newString;
END//
DELIMITER ;

With the following request:

SELECT UC_DELIMITER('ThIs IS an ExAMplE oF MIxeD CaseS sTRing',' ',TRUE);

You will get:

This Is An Example Of Mixed Cases String

This can be done by using LOWER, UPPER and SUBSTRING functions, see below sample query

Select CONCAT(UPPER(SUBSTRING(name,1,1)),LOWER(SUBSTRING(name,2))) AS Name from table;

In an UPDATE query this will be

UPDATE table1 SET name = CONCAT(UPPER(SUBSTRING(name,1,1)),LOWER(SUBSTRING(name,2))) WHERE 1
Related