Postgres query: array_to_string with empty values - postgresql

I am trying to combine rows and concatenate two columns (name, vorname) in a Postgres query.
This works good like this:
SELECT nummer,
array_to_string(array_agg(name|| ', ' ||vorname), '\n') as name
FROM (
SELECT DISTINCT
nummer, name, vorname
FROM myTable
) AS m
GROUP BY nummer
ORDER BY nummer;
Unfortunately, if "vorname" is empty I get no results although name has a value.
Is it possible get this working:
array_to_string(array_agg(name|| ', ' ||vorname), '\n') as name
also if one column is empty?

Use coalesce to convert NULL values to something that you can concatenate:
array_to_string(array_agg(name|| ', ' ||coalesce(vorname, '<missing>')), '\n')
Also, you can concatenate strings directly without collecting them to an array by using the string_agg function.

If you have 9.1, then you can use third parameter for array_to_string - null string
array_to_string(array_agg(name), ',', '<missing>') from bbb

Related

Converting a postgresql array to a set

I'm using the (nifty!) string_agg function in postgresql to accumulate values of a given field
string_agg(r.pmid, ',' order by pmid)
This gives results like this - due to duplicate values of id's in underlying data:
15364708,15364708,15364708,15364709,15364709,15364709
How can this array / list be converted to a set ?
You could try using DISTINCT with STRING_AGG:
SELECT STRING_AGG(DISTINCT r.pmid, ',' ORDER BY pmid)
FROM yourTable
...

Concatenate a column from multiple rows into a single formatted string

I have rows like so:
roll_no
---------
0690543
0005331
0760745
0005271
And I want string like this :
"0690543.pdf" "0005331.pdf" "0760745.pdf" "0005271.pdf"
I have tried concat but unable to do so
You can use an aggregate function like string_agg, after first mangling the quotes and the .pdf extension to your column data. Use a space as your delimiter:
SELECT string_agg('"'||roll_no||'.pdf "', ' ') from myTable
SqlFiddle here

Need help in parsing column value based on value in other column

I have two columns, COL1 and COL2. COL1 has value like 'Birds sitting on $1 and enjoying' and COL2 has value like 'the.location_value[/tree,\building]'
I need to update third column COL3 with values like 'Birds sitting on /tree and enjoying'
i.e. $1 in 1st column is replaced with /tree
which is the 1st word from list of comma separated words with in square brackets [] in COL2 i.e. [/tree,\building]
I wanted to know the best suitable combination of string function in postgresql to use to achieve this.
You need to first extract the first element from the comma separated list, to do that, you can use split_part() but you first need to extract the actual list of values. This can be done using substring() with a regular expression:
substring(col2 from '\[(.*)\]')
will return /tree,\building
So the complete query would be:
select replace(col1, '$1', split_part(substring(col2 from '\[(.*)\]'), ',', 1))
from the_table;
Online example: http://rextester.com/CMFZMP1728
This one should work with any (int) number after $:
select t.*, c.col3
from t,
lateral (select string_agg(case
when o = 1 then s
else (string_to_array((select regexp_matches(t.col2, '\[(.*)\]'))[1], ','))[(select regexp_matches(s, '^\$(\d+)'))[1]::int] || substring(s from '^\$\d+(.*)')
end, '' order by o) col3
from regexp_split_to_table(t.col1, '(?=\$\d+)') with ordinality s(s, o)) c
http://rextester.com/OKZAG54145
Note:it is not the most efficient though. It splits col2's values (in the square brackets) each time for replacing $N.
Update: LATERAL and WITH ORDINALITY is not supported in older versions, but you could try a correlating subquery instead:
select t.*, (select array_to_string(array_agg(case
when s ~ E'^\\$(\\d+)'
then (string_to_array((select regexp_matches(t.col2, E'\\[(.*)\\]'))[1], ','))[(select regexp_matches(s, E'^\\$(\\d+)'))[1]::int] || substring(s from E'^\\$\\d+(.*)')
else s
end), '') col3
from regexp_split_to_table(t.col1, E'(?=\\$\\d+)') s) col3
from t

SQL query to Break on row into multiple row based on some delimiter

I have a table named `test' which has following structure.
category key value
name real_name:Brad,nick_name:Brady,name_type:small NOVALUE
other description cool
But I want to break key column into multiple rows based on , delimiter and value after : delimiter should be a part of value column where value is equal to NOVALUE. So output should look like:
category key value
name real_name Brad
name nick_name Brady
name name_type small
other description cool
How to write sql query for this . I am using postgresql.
Any help ? Thanks in advance.
You can use string_to_array and unnest to do this:
select ts.category,
split_part(key_value, ':', 1) as key,
split_part(key_value, ':', 2) as value
from test ts
cross join lateral unnest(string_to_array(ts.key, ',')) as t (key_value)
where ts.value = 'NOVALUE'
union all
select category,
key,
value
from test
where value <> 'NOVALUE';
SQLFiddle example: http://sqlfiddle.com/#!15/6f1e6/1
select category,
split_part(key_value, ':', 1) as key,
case when value = 'NOVALUE' then split_part(key_value, ':', 2) else value end
from test
cross join lateral unnest(string_to_array(key, ',')) as t (key_value)

Split a column value into two columns in a SELECT?

I have a string value in a varchar column. It is a string that has two parts. Splitting it before it hits the database is not an option.
The column's values look like this:
one_column:
'part1 part2'
'part1 part2'
So what I want is a a result set that looks like:
col1,col2:
part1,part2
part1,part2
How can I do this in a SELECT statement? I found a pgsql function to split the string into an array but I do not know how to get it into two columns.
select split_part(one_column, ' ', 1) AS part1,
split_part(one_column, ' ', 2) AS part2 ...