假设你拥有的每行10个技能的限制,你可以正常化skills
列用下面的查询:
select distinct
s.fname, s.lname,
replace(
substring(substring_index(s.skills, ',', p.pos),
char_length(substring_index(s.skills, ',', p.pos -1)) + 1),
',', ''
) as skill
from
skills s
cross join
(select 1 pos
union all select 2
union all select 3
union all select 4
union all select 5
union all select 6
union all select 7
union all select 8
union all select 9
union all select 10
) p on p.pos <= (char_length(s.skills) - char_length(replace(s.skills, ',', ''))) + 1
结果:
| fname | lname | skill |
|-------|-------|--------|
| Jane | Doe | php |
| Jane | Doe | java |
| Jane | Doe | mongo |
| Jane | Doe | mysql |
| Jane | Doe | oracle |
sqlfiddle
(char_length(s.skills) - char_length(replace(s.skills, ',', ''))) + 1
将返回的技能数(计数的逗号)。
replace(
substring(substring_index(s.skills, ',', p.pos),
char_length(substring_index(s.skills, ',', p.pos -1)) + 1),
',', ''
)
将在给定的位置提取技能。
不用内联创建位置表,您可以使用具有不间断数字序列的任何现有表。
要再次非规范化的结果,你可以使用GROUP_CONCAT(DISTINCT skill)
:
select
s.fname, s.lname,
group_concat(distinct replace(
substring(substring_index(s.skills, ',', p.pos),
char_length(substring_index(s.skills, ',', p.pos -1)) + 1),
',', ''
)) as skills
from skills s
cross join (
select 1 pos
union all select 2
union all select 3
union all select 4
union all select 5
union all select 6
union all select 7
union all select 8
union all select 9
union all select 10
) p on p.pos <= (char_length(s.skills) - char_length(replace(s.skills, ',', ''))) + 1
group by s.fname, s.lname
结果:
| fname | lname | skills |
|-------|-------|-----------------------------|
| Jane | Doe | php,mysql,mongo,oracle,java |
sqlfiddle
这样没有技能在列表中出现两次。
删除查询显示语法错误 – VipinS
您能提供错误吗? @vipins – sagi
@VipinS您是否已将'YourTable'更改为您的实际表名? – sagi