[英]How do I replace/update all instances of every string in a column with matching values from another table?
Storing data in comma separated strings wasn't up to me and it isn't something I can change in my database so bear with me. 在逗号分隔的字符串中存储数据不是由我决定的,这不是我可以在我的数据库中更改的内容所以请耐心等待。 I did quite a bit of searching already online and on stackoverflow but I couldn't find a solution to this, if it's even possible using MySQL.
我已经在网上和stackoverflow上进行了相当多的搜索但是我找不到解决方案,如果它甚至可以使用MySQL。
I am trying to replace all instances of every unique string from table1 with a matching value from table2. 我试图用table2中的匹配值替换table1中每个唯一字符串的所有实例。 I have tried wildcards, replace, update, join, etc and I'm just not sure how to make it work.
我尝试过通配符,替换,更新,加入等等,我只是不确定如何使它工作。 I know one solution would be replace() for each string but table2 has over 200 rows so that would mean nesting over 200 times.
我知道每个字符串的一个解决方案是replace(),但table2有超过200行,这意味着嵌套超过200次。
Here's what I'm trying to accomplish. 这就是我想要完成的事情。 I have two tables, table1:
我有两个表,table1:
+------+-------------+
| Item | Code |
+------+-------------+
| 1 | 614 |
+------+-------------+
| 2 | 212,614,415 |
+------+-------------+
| 3 | 212,303 |
+------+-------------+
| ... | ... |
+------+-------------+
and table2: 和table2:
+------+-------------------+
| Code | Name |
+------+-------------------+
| 614 | Columbus, OH |
+------+-------------------+
| 212 | New York, NY |
+------+-------------------+
| 415 | San Francisco, CA |
+------+-------------------+
| 303 | Ft. Worth, TX |
+------+-------------------+
| ... | ... |
+------+-------------------+
I want to replace codes from table1 with the corresponding values from table2 to produce this result: 我想用table2中的相应值替换table1中的代码以生成此结果:
+------+---------------------------------------------+
| Item | Code |
+------+---------------------------------------------+
| 1 | Columbus, OH |
+------+---------------------------------------------+
| 2 | New York, NY,Columbus, OH,San Francisco, CA |
+------+---------------------------------------------+
| 3 | New York, NY,Ft. Worth, TX |
+------+---------------------------------------------+
| ... | ... |
+------+---------------------------------------------+
This should do it (see the last query below). 这应该这样做(参见下面的最后一个查询)。 I've included the commas in the join so that and id of something like 12 does not match where you have and id of 212 (for example).
我在连接中包含了逗号,因此像12这样的id与你所拥有的id和212的id不匹配(例如)。
drop table if exists table1;
drop table if exists table2;
create table table1(
item int,
code varchar(64)
);
create table table2(
code int,
name varchar(64)
);
insert into table1 values (1, '614');
insert into table1 values (2, '212,614,415');
insert into table1 values (3, '212,303');
insert into table2 values(212, 'New York, NY');
insert into table2 values(303, 'Ft. Worth, TX');
insert into table2 values(415, 'San Francisco, CA');
insert into table2 values(614, 'Columbus, OH');
select * from table1
+ --------- + --------- +
| item | code |
+ --------- + --------- +
| 1 | 614 |
| 2 | 212,614,415 |
| 3 | 212,303 |
+ --------- + --------- +
3 rows
select * from table2
+ --------- + --------- +
| code | name |
+ --------- + --------- +
| 212 | New York, NY |
| 303 | Ft. Worth, TX |
| 415 | San Francisco, CA |
| 614 | Columbus, OH |
+ --------- + --------- +
4 rows
select
t1.item,
t2.name
from
table1 t1 join table2 t2 on (
t1.code = t2.code
or t1.code like concat(t2.code, ',%')
or t1.code like concat('%,', t2.code, ',%')
or t1.code like concat('%,', t2.code)
)
order by t1.item
+ --------- + --------- +
| item | name |
+ --------- + --------- +
| 1 | Columbus, OH |
| 2 | Columbus, OH |
| 2 | New York, NY |
| 2 | San Francisco, CA |
| 3 | Ft. Worth, TX |
| 3 | New York, NY |
+ --------- + --------- +
6 rows
EDIT: or if you want to keep the data denormalized like this: 编辑:或者如果你想保持数据非规范化,如下所示:
select
t1.item,
group_concat(t2.name)
from
table1 t1 join table2 t2 on (
t1.code = t2.code
or t1.code like concat(t2.code, ',%')
or t1.code like concat('%,', t2.code, ',%')
or t1.code like concat('%,', t2.code)
)
group by t1.item
order by t1.item
+ --------- + -------------------------- +
| item | group_concat(t2.name) |
+ --------- + -------------------------- +
| 1 | Columbus, OH |
| 2 | Columbus, OH,New York, NY,San Francisco, CA |
| 3 | Ft. Worth, TX,New York, NY |
+ --------- + -------------------------- +
3 rows
And here we see a perfect example of why using comma-separated lists in DB fields is a bad idea. 在这里,我们看到一个完美的例子,说明为什么在数据库字段中使用逗号分隔列表是一个坏主意。 They are tons harder to manipulate than a proper relational table.
它们比合适的关系表更难操纵。
With that in mind I would consider first splitting the code into multiple records, then doing the easy set based replace, and then putting them back together. 考虑到这一点,我会考虑首先将代码拆分为多个记录,然后执行基于简单集的替换,然后将它们重新组合在一起。 Essentially:
实质上:
Using a split function to create a temp table tmp1 with 1 record for each item/code pair. 使用split函数创建临时表tmp1,每个项目/代码对包含1条记录。
Then do an UPDATE on the tmp1.code from tmp1 joined to table1. 然后从tmp1加入到table1的tmp1.code上执行UPDATE。
Finally use GROUP_CONCAT to put the Names back together. 最后使用GROUP_CONCAT将名称重新组合在一起。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.