Suppose a PostgreSQL table, articles
, contains two nullable String columns of name
and alt_name
.
Now, I want to find records (rows) in the table that have
- a combination of String
name
andalt_name
matches another combination of the same type in the same table:- i.e.,
[a.name, a.alt_name]
is equal to either[b.name, b.alt_name]
or[b.alt_name, b.name]
- i.e.,
- where
name
oralt_name
may beNULL
or an empty String, and in any circumstancesNULL
and an empty String should be treated as identical;- e.g., when
[a.name, a.alt_name] == ["abc", NULL]
, a record of[b.name, b.alt_name] == ["", "abc"]
should match, because one of them is"abc"
and the other is NULL or empty String.
- e.g., when
Is there any neat query to achieve this?
I thought if there is a way to concatenate both columns with a UTF-8 replacement character (U+FFFD
) in between, where NULL is converted into an empty String, that would solve the problem. Say, if the function were magic_fn()
, the following would do a job, providing there is a unique column id
:
SELECT * FROM articles a INNER JOIN places b ON a.id <> b.id
WHERE
magic_fn(a.name, a.alt_name) = magic_fn(b.name, b.alt_name)
OR magic_fn(a.name, a.alt_name) = magic_fn(b.alt_name, b.name);
-- [EDIT] corrected from the original post, which was simply wrong.
However, concatnation is not a built-in function in PostgreSQL and I don't know how to do this.
[EDIT] As commented by @Serg and in answers, a string-concatnation function is now available in PostgreSQL from Ver.9.1 (CONCAT or ||); n.b., it actually accepts non-String input as long as one of them is a String-type as of Ver.15.
Or, maybe there is simply a better way?