Is there a simple way to convert MySQL data into Title Case?

后端 未结 11 2163
太阳男子
太阳男子 2020-11-27 15:35

I have a MySQL table where all the data in one column was entered in UPPERCASE, but I need to convert in to Title Case, with recognition of \"small words\" akin to the Darin

相关标签:
11条回答
  • 2020-11-27 15:42

    umm something like this may work

    UPDATE table_name SET `col_name`= CONCAT( UPPER( SUBSTRING( `col_name`, 1, 1 ) ) , LOWER( SUBSTRING( `col_name` FROM 2 ) ) );
    
    0 讨论(0)
  • 2020-11-27 15:43

    This one works for me.

    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
    
    0 讨论(0)
  • 2020-11-27 15:44

    I used something like this

    UPDATE `tablename` 
    SET `fieldname` =  CONCAT(UCASE(SUBSTRING(`fieldname`,1,1)),'', LCASE(SUBSTRING(`fieldname`,2,LENGTH(`fieldname`)))) 
    

    Note: This will only convert the first character to uppercase. and rest of the value to lowercase.

    0 讨论(0)
  • 2020-11-27 15:48

    My solution for simple proper case:

    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
    

    Use it as:

    SELECT proper_case("JOHN DOE");
    

    Output:

    John Doe
    
    0 讨论(0)
  • 2020-11-27 15:49

    Woo! I'm not handy with SQL at all; Here's the method that worked for me:

    1. Export the table as a text file in .sql format.
    2. Open the file in Textmate (which I already had handy).
    3. Select the rows with UPPERCASE data.
    4. Choose "Convert" from the "Text" menu, and select "to Titlecase".
    5. Find and replace each instance of:

      INSERT INTO `Table` (`Col1`, `Col2`, `Etc`, ...) VALUES
      

      with the correct lowercase values.

    6. Import the table back into the database.
    7. Use UPDATE table SET colname=LOWER(colname); to reset lowercase values for the columns that should be lowercase.

    The reason I didn't try using Textmate before was that I couldn't figure out how to convert a single column to Title Case without ruining the other data, but this method seems to work. Thanks for your guidance and support!

    0 讨论(0)
  • 2020-11-27 15:53

    Edit

    Eureka! Literally my first SQL function. No warranty offered. Back up your data before using. :)

    First, define the following function:

    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 ;
    

    This will lower all occurrences of word in str.

    Then define this modified proper function:

    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 ; 
    

    Usage

    Verify it works as expected:

    SELECT tcase(title) FROM table;
    

    Use it:

    UPDATE table SET title = tcase(title);
    

    Source: http://www.artfulsoftware.com/infotree/queries.php?&bw=1070#122

    0 讨论(0)
提交回复
热议问题