I need to convert this into this using PostgreSQL
dxItw9a4 --> DXiTW9A4
Is there any function or way that is already set?
If you're only dealing with the characters A-Z, you can use the translate function in postgres to convert cases.
select TRANSLATE(
'dxItw9a4', -- original text
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', -characters to change
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' -- replacement characters.
)
You can simplify it slightly be using the upper/lower functions.
select TRANSLATE(
'dxItw9a4', -- original text
upper('dxItw9a4')||lower('dxItw9a4'), --characters to search for
lower('dxItw9a4')||upper('dxItw9a4') -- replacement characters
);
It sounds like the OP is looking for a SQL version of the swapcase()
function found in many client-side languages. A few thoughts:
swapcase()
on the client side. I'd do that.I figured I'd give #3 a try, and wrote some code. The kindest thing I can say about this function is that it works...but I doubt it's much good. I'm trying to beef up my PL/pgSQL skills, so any comments on improving the code welcomed. It's so much easier to write a lot of things in most other languages...but there are plenty of cases where pushing the logic onto the server is beneficial, I figure it's worth putting in some effort to get comfortable in PL/pgSQL. But, again, I'd use swapcase()
, or a hand-rolled equivalent, on the client side, I'd expect.
CREATE OR REPLACE FUNCTION swapcase(in_text text) RETURNS text as
$BODY$
DECLARE
out_text text;
test_char text;
ascii_code smallint;
characters_arr_text text[];
begin
out_text :='';
test_char := '';
select into characters_arr_text regexp_split_to_array(in_text,'');
FOREACH test_char IN array characters_arr_text LOOP
ascii_code := ascii(test_char);
IF (ascii_code BETWEEN 65 and 90) THEN
out_text := out_text || LOWER(test_char);
ELSIF (ascii_code BETWEEN 97 and 122) THEN
out_text := out_text || UPPER(test_char);
ELSE
out_text := out_text || test_char;
END IF;
END LOOP;
RETURN out_text;
END
$BODY$
LANGUAGE 'plpgsql';
Here's a call:
select swapcase('dxItw9a4'); -- DXiTW9A4
And a longer call to show that it works:
select 'dxItw9a4' as input,
swapcase('dxItw9a4') as output,
'DXiTW9A4' as expected_output,
swapcase('dxItw9a4') = 'DXiTW9A4' as pass;
Here's a swapcase()
function that uses GMB's code.
CREATE OR REPLACE FUNCTION swapcase(in_text text) RETURNS text as
$BODY$
select string_agg(
case when character ~ '[a-z]' then
upper(character)
else
lower(character)
end, '') as result_text
from (select *
from regexp_split_to_table(in_text, '') as character) as subquery
$BODY$
LANGUAGE 'sql';
You can use the following methods supported by PostreSQL:
UPPER(string_expression)
Example:
SELECT
CONCAT (
UPPER (first_name),
UPPER (last_name)
) as full_name
FROM
staff;
Reference: http://www.postgresqltutorial.com/postgresql-letter-case-functions/
Here is a solution that works by splitting the string into a resultset of charaters using regexp_split_to_table()
, then converts them to the opposite case and joins them again using aggregate function string_agg()
:
select
string_agg(case when c ~ '[a-z]' then upper(c) else lower(c) end, '') res
from (
select * from regexp_split_to_table('dxItw9a4', '') as chars(c)
) x
Demo on DB Fiddle:
| res | | :------- | | DXiTW9A4 |