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

pkwftd7m  于 2021-06-24  发布在  Mysql
关注(0)|答案(4)|浏览(328)

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

| 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可以通过随机数字和字母继续。我想一个通用的解决方案,可以适用于任何数量的行和列,并在第2列值的数目。
我想在mysql中运行一个查询,搜索column2中的所有值,并输出column1中包含column2中3的字母。输出应为:

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

许多帖子都有直接完成这一任务的答案,但我想用正确的方法来做。我不熟悉sql,但我相信这意味着要通过创建一个新表并在这个新表上运行查询来规范第2列中的数据。
有人能帮我规范化代码并在mysql中运行这个查询吗?谢谢。

sh7euo9m

sh7euo9m1#

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

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

然后可以使用以下简单查询:

Select column1 from table where column2 = 3;
qvsjd97n

qvsjd97n2#

我知道这是一个老帖子,但我想我会有所贡献,因为我需要自己完成这个练习,这给了我一些想法。
这是我得到的解决方案,这里的限制条件是逗号分隔列表中的值在另一个表中唯一定义:

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秒)

8ljdwjyq

8ljdwjyq3#

你需要使用 FIND_IN_SET() ```
SELECT column1 FROM table WHERE FIND_IN_SET('3', column2);

小提琴演示
永远不要将数据作为逗号分隔的列表存储在表中。。。所以如果我是你,我会考虑把它分成几行
要规范化数据库,可以执行以下查询。。。请注意,您需要知道第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;

标准化结果
每个数字的连接是你的钥匙。。。如果您有6个项目逗号分隔,然后联合0-5位数字加入。
如果你不知道有多少,那么就运行这个来知道有多少个数字要联合

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

yizd12fk

yizd12fk4#

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

相关问题