If your strings are nicely formatted starting with a capital letter and lower-case letters otherwise, you can use a regular expression to do this:
SELECT regexp_replace(middle_name, '([a-z ])+', '.', 'g');
The regular expression "says": take one or more subsequent lowercase letters or spaces and replace it with a single dot .
. The 'g'
(global) modifier repeats this for all occurrences.
In combination with first_name
and last_name
:
SELECT concat_ws(' ', first_name,
regexp_replace(middle_name, '([a-z ])+', '.', 'g'),
last_name
) AS name
FROM my_table;
If - as seems to be the case - the name can be any combination of upper-case and lower-case letters then you must split the name into an array, take the first letter and re-assemble it:
SELECT concat_ws(' ', first_name, middle, last_name) AS name
FROM (
SELECT first_name, string_agg(left(middle, 1), '.') AS middle, last_name
FROM my_table, unnest(string_to_array(middle_name, ' ')) m(middle)
GROUP BY first_name, last_name) sub;
This assumes that there are no duplicate (first_name, last_name)
pairs. If so, you should include a primary key or some other unique row identifier.