Mysql extract first letter of each word in a specific column

后端 未结 5 1627
予麋鹿
予麋鹿 2021-01-16 02:36

I want to create an acronym column in a table. I want to be grab the first letter of each word from a \'name\' column, capitalize it, then concatenate all into an \'acronym\

相关标签:
5条回答
  • 2021-01-16 03:07

    String manipulation of this kind is not what SQL is designed for, unless you want to write a stored procedure or UDF for it.

    SQL isn't really suited for string manipulation of this sort. You may do it somehow but why would you when better tools are available elsewhere? I went on a long search on Google to find such a query statement but I couldn't. Just use the following function to achieve what you want.

    drop function if exists initials;
    delimiter ||
    create function initials(str text) returns text
    begin
        declare result text default '';
        declare i int default 1;
    
        if(str is null) then
            return null;
        end if;
    
        set result = upper(substr(str, 1, 1));
    
        while(i <= length(str)) do
            if (substring(str, i, 1) = ' ')
            then
                set result = concat(result, upper(substr(str, i+1, 1)));
            end if;
           set i = i + 1;
        end while;
    
        return ucase(result);
    end;
    delimiter ;
    
    0 讨论(0)
  • 2021-01-16 03:09

    This should get all the first letters into a result set:

    SELECT UPPER(SUBSTR(name, 0, 1)) FROM the_table
    

    Concatenating them all into a single acronym would, I think, require a procedure of some kind. I don't think it can be done in a statement.

    0 讨论(0)
  • 2021-01-16 03:10

    Here is an "improved" function, allowing to filter only wanted characters thanks to a regular expression.

    • function initials does the actual job, you have to specify the regular expression
    • function acronym does the job keeping Alpha-numeric characters only

    (Use upper, lower or ucase functions on the output if necessary) .

    delimiter $$
    drop function if exists `initials`$$
    CREATE FUNCTION `initials`(str text, expr text) RETURNS text CHARSET utf8
    begin
        declare result text default '';
        declare buffer text default '';
        declare i int default 1;
        if(str is null) then
            return null;
        end if;
        set buffer = trim(str);
        while i <= length(buffer) do
            if substr(buffer, i, 1) regexp expr then
                set result = concat( result, substr( buffer, i, 1 ));
                set i = i + 1;
                while i <= length( buffer ) and substr(buffer, i, 1) regexp expr do
                    set i = i + 1;
                end while;
                while i <= length( buffer ) and substr(buffer, i, 1) not regexp expr do
                    set i = i + 1;
                end while;
            else
                set i = i + 1;
            end if;
        end while;
        return result;
    end$$
    
    drop function if exists `acronym`$$
    CREATE FUNCTION `acronym`(str text) RETURNS text CHARSET utf8
    begin
        declare result text default '';
        set result = initials( str, '[[:alnum:]]' );
        return result;
    end$$
    delimiter ;
    

    Example1:

    select acronym('Come Again? That Cant Help!');
    

    Outputs:

    CATCH

    Example2:

    select initials('Come Again? That Cant Help!', '[aeiou]');
    

    Outputs:

    oeAaaae

    0 讨论(0)
  • 2021-01-16 03:13

    Do you mean LEFT and UPPER?

    0 讨论(0)
  • 2021-01-16 03:28

    I know this is a little late to the game, but I wanted to offer up a non-function way of doing this for those of you creating a view or a .sql file for periodic use:

    SELECT
        @spaces:= length(fi.FacilityName) - length(replace(fi.FacilityName,' ','')) as spaces,
        concat(left(fi.FacilityName,1),
            if(@spaces > 0, substring(fi.FacilityName,@pos:=locate(' ',fi.FacilityName)+1,1),''),
            if(@spaces > 1, substring(fi.FacilityName,@pos:=locate(' ',fi.FacilityName, @pos)+1,1),''),
            if(@spaces > 2, substring(fi.FacilityName,@pos:=locate(' ',fi.FacilityName,@pos)+1,1),''),
            if(@spaces > 3, substring(fi.FacilityName,@pos:=locate(' ',fi.FacilityName,@pos)+1,1),''),
            if(@spaces > 4, substring(fi.FacilityName,@pos:=locate(' ',fi.FacilityName,@pos)+1,1),'')) as initials
    from facilityInfo fi
    

    It's two steps, and you have to include a conditional substring() line for every word you anticipate being in the string, but that is just a copy, paste, and increment of the comparison value for @spaces. My requirements for doing this may be a little looser than some, however. Regardless, it works and causes no noticeable speed issues.

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