如何规范化表格列中的逗号分隔值,然后运行查询

时间:2014-10-12 02:38:17

标签: mysql csv normalization

我们假设我有一个具有以下结构的表:

 | column1    |    column2       |
 |------------|------------------|
 | a          |    1,L,3,K,5,    |
 | b          |    R,6,7,8,9     |
 | c          |    8,9,10,D      |
 | d          |    1,2,3,H       |

让我们说column1可以继续通过z继续,而column2可以继续使用随机数字和字母。我想要一个通用的解决方案,可以应用于任意数量的行和列,以及column2中的值数。

我想在MySQL中运行一个查询,它将搜索column2中的所有值,并输出column1中包含column2中3的字母。输出应为:

 | column1    |
 |------------|
 | a          | 
 | d          |  

许多帖子都有可以直接完成此操作的查询的答案,但我想以正确的方式执行此操作。我是sql的新手,但我相信这意味着通过创建一个新表并在这个新表上运行查询来规范化column2中的数据。

有人可以帮助我使用代码来规范化并在MySQL中运行此查询吗?感谢。

4 个答案:

答案 0 :(得分:1)

您需要使用FIND_IN_SET()

SELECT column1 FROM table WHERE FIND_IN_SET('3', column2);

Fiddle Demo

你应该从不以逗号分隔列表的形式将数据存储在表格中......所以,如果我是你,我会考虑将其分成行

要规范化您的数据库,您可以执行这样的查询...注意您需要知道第2列中的数量..

CREATE TEMPORARY TABLE IF NOT EXISTS normalized_table AS 
(   SELECT
      column1,
      SUBSTRING_INDEX(SUBSTRING_INDEX(column2, ',', n.digit+1), ',', -1) column2
    FROM test
    JOIN(SELECT 0 digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4) n
        ON LENGTH(REPLACE(column2, ',' , '')) <= LENGTH(column2)-n.digit
    ORDER BY column1, n.digit
);

DROP table test;
CREATE table test (column1 varchar(2), column2 varchar(2));
INSERT INTO test (column1, column2) 
SELECT column1, column2 FROM normalized_table;

NORMALIZED RESULTS

每个数字的JOIN是你的关键......如果你有6个逗号分隔的项目,那么联合0-5个数字就可以加入。

如果您不知道有多少,那么只需运行它就可以知道要合并多少个数字

SELECT MAX(LENGTH(REPLACE(column2, ',', ''))) FROM test;

答案 1 :(得分:1)

要规范化此表,您可能希望使用由两列组成的表,主键是两列。它看起来像这样:

| column1    |    column2       |
|------------|------------------|
| a          |    1             |
| a          |    3             |
| a          |    L             |
| b          |    R             |
| c          |    8             |
| d          |    3             |

然后你可以使用这个简单的查询:

Select column1 from table where column2 = 3;

答案 2 :(得分:1)

我知道这是一篇很老的帖子,但我认为我有所贡献,因为我需要自己进行这项练习,这给了我一些想法。

这是我到达的解决方案,这里的附带条件是逗号分隔列表中的值是在另一个表中唯一定义的:

create table `defined_values` (
  id int(11) not null auto_increment primary key,
  label varchar(12) not null,
  constraint `defined_values_uidx` unique (`label`)
) engine = innodb charset utf8;

create table `delimited_string` (
  id int(11) not null auto_increment primary key,
  `str_delim` varchar(32) not null
) engine = innodb charset utf8;

insert into `defined_values` (`label`) values
('YVR'),
('YEG'),
('YXJ'),
('YYC'),
('YMM')
;

insert into `delimited_string` (`str_delim`) values 
('YVR,YEG,YXJ,YYC,YMM')
;

select 
  v.`label` as `normalized` 
from 
  `delimited_string` s
  join `defined_values` v on (v.`label` = substring(s.`str_delim`, position(v.`label` in s.`str_delim`), length(v.`label`))) 

//收益率:

+------------+
| normalized | 
+------------+
| YEG        |
| YMM        |
| YVR        |
| YXJ        |
| YYC        |
+------------+

5行(0.00秒)

答案 3 :(得分:0)

select column1 from your_tab where 3 in (column2)

或者您可以使用

select column1 from your_tab where column2 like '3,%' or column2 like '%,3' or column2 like '%,3,%' or column2=3