MySQL - select 来自一列的不同值,其中值以逗号分隔
MySQL - select distinct values from a column where values are separated by comma
要从 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
有什么想法吗?
你不能。您的数据库不遵守设计规范化数据库的首要原则:- 原子性。它说在一列中存储一个且只有一个属性,但你有这么多。您需要从您的应用程序中检索整个列值、拆分和 de-dupe 它们。 SQL 无法为您完成此操作。
您在这里真正需要做的是拥有一个单独的 NAMES table 并在过滤相关行后在名称列上应用 DISTINCT。
你必须把它们分开。如果列中最多有三个名称,则一种方法是:
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 '%,%,%';
通用方法使用递归查询(仅在 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
示例数据:
| column1 |
| :---------------- |
| name1,name2 |
| name2,name3 |
| name4,name1,name3 |
结果:
| word |
| :---- |
| name1 |
| name2 |
| name3 |
| name4 |
要从 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
有什么想法吗?
你不能。您的数据库不遵守设计规范化数据库的首要原则:- 原子性。它说在一列中存储一个且只有一个属性,但你有这么多。您需要从您的应用程序中检索整个列值、拆分和 de-dupe 它们。 SQL 无法为您完成此操作。
您在这里真正需要做的是拥有一个单独的 NAMES table 并在过滤相关行后在名称列上应用 DISTINCT。
你必须把它们分开。如果列中最多有三个名称,则一种方法是:
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 '%,%,%';
通用方法使用递归查询(仅在 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
示例数据:
| column1 | | :---------------- | | name1,name2 | | name2,name3 | | name4,name1,name3 |
结果:
| word | | :---- | | name1 | | name2 | | name3 | | name4 |