String concatenation with a null seems to nullify the entire string - is that desired behavior in Postgres?
Quote from documentation
Concatenate all arguments. NULL arguments are ignored.
Example
concat('abcde', 2, NULL, 22)
Returns
abcde222
See more in Documentation
It's not a bug and it's not "weird".
The SQL standard requires any expression that involves null
yields null
. This is not limited to string concatenation, it also applies to computations e.g.: 42 * null
returns null
.
This also applies to comparisons: 42 > null
yields null
. So the comparison it's neither true nor false. Although in reality this has the effect of "false", but more because it's "not true", rather then false. But negating such an expression yields null
again, not "true".
Because null
is so special, the only way to check if something is null is to use the operator IS NULL
or IS NOT NULL
. x is null
yields either true or false, it never yields null
, so expressions using the is null
or is not null
operator never return null - so this is an exception to my statement above (thanks Jonathan for pointing that out).
Another - maybe surprising - fact about null
values is how they are handled by aggregate functions. While the expression 4 + 5 + null
yields null, the sum()
over those (column) values would yield 9, because aggregates ignore null
values.
Given the following table:
col1
--------
1
2
3
null
sum(col1)
will return 6, and avg(col1)
will return 2
(sum = 6, number of elements added: 3)
Yes, it is desired behavior.
Here is an example in which it is very useful. Let's say you have a persons table an in it the fields title
, firstname
, nameaffix
and lastname
. To build a full name you can simply do this.
COALESCE(title || ' ', '') || firstname || COALESCE(' ' || nameaffix, '') || ' ' || lastname
Without that strange behavior that would be quite an afford to place the spaces at the right spots depending on whether a field is null or not. Assuming a mandatory first name and last name any combination of title and name affix is covered.