Let’s say I have a table t, 2 of its columns are A1 and A2. It looks something like this:
A1 | A2 | ID |
---|---|---|
1,3,6,9,11 | 3,9 | 1 |
2,3,5,7 | 3 | 2 |
… |
I want to add a column with the result:
A3 |
---|
1,6,11 |
2,5,7 |
… |
The values are actually strings, but I’m assuming dealing with arrays is easier, and that STRING_TO_ARRAY and ARRAY_TO_STRING will work (beginning and ending).
We can assume that:
- A2 will never have values that are not in A1.
- A2 will never be equal to A1.
Also, A2 can be null, but I am guessing that a CASE will solve this.
I know PostgreSQL has the function ARRAY_REMOVE(). So I tried unnesting, but then I have two different arrays, one without a ‘3’, another without a ‘9’ (first example). So I would like its intersection, but I also don’t know how to do that and whether it’s easier than my initial problem or if I’m just trying to solve a difficult problem (for me, at least) by trying to solve an even more difficult one.
I also tried something like this, that I kind of understand why it didn’t work:
SELECT ID, ARRAY_AGG(elem)
from t, UNNEST(STRING_TO_ARRAY(A1,',')) elem
where elem <> all(
SELECT UNNEST(STRING_TO_ARRAY(A2,',')) FROM t
)
GROUP BY ID
Probably worth mentioning that I am a couple weeks into learning SQL, so there might be ways to do things that I don’t know about.
2
Answers
You can
string_to_array()
first, like you planned to, then make that anint[]
which you can subtract with a simple-
fromintarray
extension.demo at db<>fiddle
Note that intarray’s
-
subtraction is set-based – it will deduplicate the inputs.Unnest/aggregate these array elements of
A1
that do not exist inA2
. Basically this is the same idea as in your query.the_table
CTE is a mimic of real data,t
CTE has the strings convered to arrays.DB Fiddle demo