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\
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 ;
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.
Here is an "improved" function, allowing to filter only wanted characters thanks to a regular expression.
initials
does the actual job, you have to specify the regular expressionacronym
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
Do you mean LEFT and UPPER?
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.