I have a table with three columns. Two of the columns (str1 and str2) are nullable strings and the other is a nullable array of strings (arr). I need to collect all of these into a single column arr while removing possible duplicate values (the original array column is guaranteed not to have duplicates).
The best I've been able to do is add one string column at a time, but I'd like to know if there's a better way:
WITH foo AS (
SELECT 'A' AS str1, 'B' AS str2, ['C', 'D'] AS arr UNION ALL
-- all get concatenated
-- ['C', 'D', 'A', 'B']
SELECT 'A' AS str1, 'B' AS str2, ['C', 'A'] AS arr UNION ALL
SELECT 'A' AS str1, 'A' AS str2, ['C', 'D'] AS arr UNION ALL
-- 'A' is not duplicated
-- ['C', 'A', 'B'] and ['C', 'D', 'A']
SELECT NULL AS str1, 'B' AS str2, ['C', 'A'] AS arr UNION ALL
-- NULL str1 (or str2) is ignored
-- ['C', 'A', 'B']
SELECT 'A' AS str1, 'B' AS str2, NULL AS arr UNION ALL
-- NULL array is ignored, str1 and 2 are array_concat'ed
-- ['A', 'B']
SELECT NULL AS str1, NULL AS str2, NULL AS arr
-- handles all NULLs
-- NULL ([] or [''] would be ok)
)
SELECT CASE WHEN str2 IS NULL
OR str2 IN UNNEST(arr)
THEN arr
WHEN arr IS NULL
THEN [str2]
ELSE ARRAY_CONCAT(arr, [str2])
END AS arr
FROM (
SELECT CASE WHEN str1 IS NULL
OR str1 IN UNNEST(arr)
THEN arr
WHEN arr IS NULL
THEN [str1]
ELSE ARRAY_CONCAT(arr, [str1])
END AS arr
, str2
FROM foo
)
In this implementation, if all the component values are NULL, arr will be NULL. However, an empty array or an array with a single '' would also be acceptable in this situation. Also, the order of items in the final array is irrelevant.
So, is there a cleaner, smarter way of doing this?