如何为每一行仅连接 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_A
、Col_B
和 Col_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
如果结果是 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"] |
如何仅连接为 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_A
、Col_B
和 Col_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
如果结果是 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"] |