如何为每一行仅连接 MySQL 中的唯一列?

How Can I Concatenate Only Unique Columns in MySQL for Every Row?

如何仅连接为 MySQL 中的每一行指定的列的唯一列?

Table 'Example':

考虑以下名为 example 的 table:

* -------------------------- *
| Id | Col_A | Col_B | Col_C |
| -------------------------- |
| 0  | foo   | bar   | qux   |
| 1  | foo   | foo   | bar   |
| 2  | foo   | qux   | qux   |
| 3  | foo   | foo   | foo   |
* -------------------------- *

尝试:

我只想连接 Col_ACol_BCol_C 中唯一的值(仅唯一集)。这是我的尝试:

SELECT Id,
       CONCAT_WS(',', DISTINCT Col_A, Col_B, Col_C) UniqueColumnSet
  FROM Example

预期结果:

* -------------------- *
| Id | UniqueColumnSet |
| -------------------- |
| 0  | foo,bar,qux     |
| 1  | foo,bar         |
| 2  | foo,qux         |
| 3  | foo             |
* -------------------- *

收到错误:

#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

我知道您不能在 CONCAT_WS 中这样使用 DISTINCT。获得预期结果的最有效方法是什么?

使用 UNION 将它们旋转到同一列,然后使用 GROUP_CONCAT() 连接它们。 UNION 将默认删除重复项。

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

我可以想到几种方法。

一种方法是使用表达式代替 Col_B,检查 Col_B 是否匹配 Col_A,如果匹配,则 return 为 NULL。表达式检查 Col_C 以查看它是否匹配 Col_A 或 Col_B.

也是一样的

CONCAT_WS 忽略 NULL 值,所以像这样:

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

示例数据中未显示重复值不连续的情况,例如

bar foo bar

上面的查询假定我们想要 return

bar,foo

我更喜欢 Barmar 的解决方案,因为它对我来说最易读。但这也应该有效:

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

db-fidle

如果结果是 JSON 数组没问题,您可以试试这个 "hack":

select id, json_keys(json_object(Col_A, '', Col_B, '', Col_C, '')) as UniqueColumnSet
from Example;

结果:

| id  | UniqueColumnSet       |
| --- | --------------------- |
| 0   | ["bar", "foo", "qux"] |
| 1   | ["bar", "foo"]        |
| 2   | ["foo", "qux"]        |
| 3   | ["foo"]               |

db-fiddle