【问题标题】:How Can I Concatenate Only Unique Columns in MySQL for Every Row?如何在 MySQL 中为每一行仅连接唯一列?
【发布时间】:2020-10-05 04:11:50
【问题描述】:

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

表格“示例”:

考虑下表名为example

* -------------------------- *
| 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 - 您的 SQL 语法有错误;查看与您的 MariaDB 服务器版本相对应的手册,了解在 'DISTINCT Col_A, Col_B, Col_C) UniqueColumnSet 附近使用的正确语法 FROM Example LIMIT 0, 25' at line 2

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

【问题讨论】:

  • 这种问题是架构设计不佳的症状

标签: mysql set mariadb distinct concat


【解决方案1】:

使用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

【讨论】:

    【解决方案2】:

    我能想到几种方法。

    一种方法是使用表达式代替 Col_B 来检查 Col_B 是否与 Col_A 匹配,如果匹配则返回 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
    

    上面的查询假设我们想要返回

    bar,foo
    

    【讨论】:

      【解决方案3】:

      我更喜欢 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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-11-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-24
        • 1970-01-01
        • 1970-01-01
        • 2015-10-12
        相关资源
        最近更新 更多