【问题标题】:MySQL - select distinct values from a column where values are separated by commaMySQL - 从值用逗号分隔的列中选择不同的值
【发布时间】:2021-01-19 11:47:27
【问题描述】:

从 table1 和 column1 中获取不同值的列表就像这样做一样简单:

SELECT distinct(column1) 
FROM table1

但是,我继承了(不幸的是)一个数据库,其中 column1 包含用逗号分隔的值

column1
--------
row 1: name1,name2
row 2: name2,name3
row 3: name4,name1,name3

我需要从 column1 中获取不同值的列表,所以它看起来像这样:

column1
--------
name1
name2
name3
name4

有什么想法吗?

【问题讨论】:

  • 请阅读stackoverflow.com/questions/3653462/…mysql自然不能这样做你必须使用函数或存储过程
  • 并注意 DISTINCT 不是函数
  • 请阅读有关数据库规范化的信息。并且请尽可能避免在列中使用逗号分隔的值。他们系统地破坏了 SQL 查询优化。
  • 请不要再谈论数据库规范化了,我无法解决其他人创建的问题...另外,有人已经针对这个问题发布了一个非常优雅的解决方案

标签: mysql sql string csv recursive-query


【解决方案1】:

通用方法使用递归查询(仅在 MySQL 8.0 中可用):

with recursive 
    data as (select concat(column1, ',') rest from mytable),
    words as (
        select substring(rest, 1, locate(',', rest) - 1) word, substring(rest, locate(',', rest) + 1) rest
        from data
        union all
        select substring(rest, 1, locate(',', rest) - 1) word, substring(rest, locate(',', rest) + 1) rest
        from words
        where locate(',', rest) > 0
)
select distinct word from words order by word

Demo on DB Fiddle

样本数据:

|第 1 列 | | :---------------- | |名称1,名称2 | |名称 2,名称 3 | |名称 4,名称 1,名称 3 |

结果:

|词 | | :---- | |名称1 | |名称2 | |名称3 | |名称4 |

【讨论】:

  • omg,这样一个优雅的解决方案,它也像一个魅力......谢谢你
  • 在我的服务器上,从 160k 行中提取和排序不同的值大约需要 10 秒...非常适合居住,...现在我有了这些值,我可以轻松改进我的应用程序
【解决方案2】:

您必须将它们分开。如果列中最多有三个名称,那么一种方法是:

select substring_index(column1, ',', 1) as name
from t
union -- on purpose to remove duplicates
select substring_index(substring_index(column1, ',', 2), ',', -1) as name
from t
where name like '%,%'
union -- on purpose to remove duplicates
select substring_index(substring_index(column1, ',', 3), ',', -1) as name
from t
where name like '%,%,%';

【讨论】:

    【解决方案3】:

    你不能。您的数据库不遵守设计规范化数据库的第一原则:- 原子性。它说在一列中存储一个且只有一个属性,但你有这么多。您需要检索整个列的值,从您的应用程序中拆分和删除它们。 SQL 无法为您执行此操作。

    你真正需要做的是有一个单独的 NAMES 表,并在过滤相关行后对 name 列应用 DISTINCT。

    【讨论】:

    • 这不是我的数据库,所以谁不遵守规范化原则,就不是我。无论如何,我手头还有一个问题需要以某种方式解决。不过感谢您的回答。
    • 一个简单的“否”不会帮助读者完全理解问题,因此我不得不解释这里出了什么问题。我还提到这只能由应用程序完成。我不明白为什么答案仍然被否决。
    猜你喜欢
    • 1970-01-01
    • 2021-02-06
    • 2023-03-21
    • 2020-12-16
    • 2020-01-19
    • 1970-01-01
    • 2012-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多