Reputation: 21
Table 'Example':
Consider the following table named example
:
* -------------------------- *
| Id | Col_A | Col_B | Col_C |
| -------------------------- |
| 0 | foo | bar | qux |
| 1 | foo | foo | bar |
| 2 | foo | qux | qux |
| 3 | foo | foo | foo |
* -------------------------- *
Attempt:
I would like to concatenate only the values in Col_A
, Col_B
, and Col_C
that are unique (only the unique set). This was my attempt:
SELECT Id,
CONCAT_WS(',', DISTINCT Col_A, Col_B, Col_C) UniqueColumnSet
FROM Example
Expected Result:
* -------------------- *
| Id | UniqueColumnSet |
| -------------------- |
| 0 | foo,bar,qux |
| 1 | foo,bar |
| 2 | foo,qux |
| 3 | foo |
* -------------------- *
Error Received:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'DISTINCT Col_A, Col_B, Col_C) UniqueColumnSet FROM Example LIMIT 0, 25' at line 2
I am aware that you cannot use DISTINCT
like this in CONCAT_WS
. What would be the most efficient method to obtain the expected result?
Upvotes: 0
Views: 55
Reputation: 31792
I prefer Barmar's solution, since it's the most readable for me. But this should work too:
select id, concat_ws(',',
Col_A,
NULLIF(Col_B, Col_A), -- NULL if Col_B = Col_A
NULLIF(NULLIF(Col_C, Col_A), Col_B) -- NULL if Col_C = Col_A or Col_C = Col_B
) as UniqueColumnSet
from Example
If you are fine with a JSON array as result, you can try this "hack":
select id, json_keys(json_object(Col_A, '', Col_B, '', Col_C, '')) as UniqueColumnSet
from Example;
Result:
| id | UniqueColumnSet |
| --- | --------------------- |
| 0 | ["bar", "foo", "qux"] |
| 1 | ["bar", "foo"] |
| 2 | ["foo", "qux"] |
| 3 | ["foo"] |
Upvotes: 1
Reputation: 781028
Use UNION
to pivot them into the same column, then use GROUP_CONCAT()
to concatenate them. UNION
will remove duplicates by default.
SELECT id, GROUP_CONCAT(col) AS UniqueColumnSet
FROM (
SELECT id, col_a AS col
FROM Example
UNION
SELECT id, col_b AS col
FROM Example
UNION
SELECT id, col_c AS col
FROM Example
) AS x
GROUP BY id
Upvotes: 2
Reputation: 108400
There's a couple of approaches I can think of.
One would be to use expression in place of Col_B that checks to to see if Col_B matches Col_A, and return a NULL if it does. Same thing for an expression to check Col_C to see if it matches Col_A or Col_B.
CONCAT_WS ignores NULL values, so something like this:
SELECT t.id
, CONCAT_WS(','
, t.Col_A
, IF(t.Col_B IN (t.Col_A), NULL, t.Col_B)
, IF(t.Col_C IN (t.Col_A,t.Col_B), NULL, t.Col_C)
) AS UniqueColumnSet
FROM `example` t
ORDER BY t.id
Not shown in the example data is a case where the duplicate values are not contiguous, for example
bar foo bar
the query above assumes that we'd want to return
bar,foo
Upvotes: 1