如何用另一个表中的匹配值替换/更新列中每个字符串的所有实例?
Posted
技术标签:
【中文标题】如何用另一个表中的匹配值替换/更新列中每个字符串的所有实例?【英文标题】:How do I replace/update all instances of every string in a column with matching values from another table? 【发布时间】:2015-06-15 18:35:43 【问题描述】:以逗号分隔的字符串存储数据不取决于我,我无法在我的数据库中更改它,所以请耐心等待。我已经在网上和 *** 上进行了大量搜索,但我找不到解决方案,如果它甚至可以使用 mysql。
我正在尝试用 table2 中的匹配值替换 table1 中每个唯一字符串的所有实例。我已经尝试过通配符、替换、更新、加入等,但我只是不确定如何使其工作。我知道一个解决方案是为每个字符串替换(),但 table2 有超过 200 行,所以这意味着嵌套超过 200 次。
这就是我想要完成的。我有两张桌子,table1:
+------+-------------+
| Item | Code |
+------+-------------+
| 1 | 614 |
+------+-------------+
| 2 | 212,614,415 |
+------+-------------+
| 3 | 212,303 |
+------+-------------+
| ... | ... |
+------+-------------+
和表2:
+------+-------------------+
| Code | Name |
+------+-------------------+
| 614 | Columbus, OH |
+------+-------------------+
| 212 | New York, NY |
+------+-------------------+
| 415 | San Francisco, CA |
+------+-------------------+
| 303 | Ft. Worth, TX |
+------+-------------------+
| ... | ... |
+------+-------------------+
我想用 table2 中的相应值替换 table1 中的代码以产生此结果:
+------+---------------------------------------------+
| Item | Code |
+------+---------------------------------------------+
| 1 | Columbus, OH |
+------+---------------------------------------------+
| 2 | New York, NY,Columbus, OH,San Francisco, CA |
+------+---------------------------------------------+
| 3 | New York, NY,Ft. Worth, TX |
+------+---------------------------------------------+
| ... | ... |
+------+---------------------------------------------+
【问题讨论】:
你试过游标吗?您可以使用光标轻松更新每个单元格 【参考方案1】:应该这样做(请参阅下面的最后一个查询)。我在连接中包含了逗号,这样 12 之类的 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
编辑: 或者如果您想像这样保持数据非规范化:
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
【讨论】:
我尝试了您的方式以及此处发布的其他方式之一。我让两者都工作,但我无法表达这种方式有多简单。节省了大量时间。谢谢! 不错。我认为 concat('%,', t2.code, '%') 需要是 concat('%,', t2.code, ',%'),对吗?那就是在结尾的 % 之前添加一个逗号。 @Karl Kieninger ...您说得对,先生。按照最初的编写方式,您会得到错误的命中(例如,如果您正在寻找 id=12 并且有 100,122,那么您会在不应该的地方获得该记录)。我将编辑答案以反映您的更正。【参考方案2】:在这里,我们看到了一个完美的例子,说明为什么在 DB 字段中使用逗号分隔的列表是一个坏主意。它们比适当的关系表更难操作。
考虑到这一点,我会考虑首先将代码拆分为多个记录,然后进行简单的基于集合的替换,然后将它们重新组合在一起。本质上:
使用 split function 创建一个临时表 tmp1,其中每个项目/代码对有 1 条记录。
然后对连接到 table1 的 tmp1 中的 tmp1.code 执行 UPDATE。
最后使用GROUP_CONCAT 将名称重新组合在一起。
【讨论】:
我花了很多额外的研究来弄清楚拆分函数/存储过程/光标部分,但这实际上是我完成工作的方式。谢谢!以上是关于如何用另一个表中的匹配值替换/更新列中每个字符串的所有实例?的主要内容,如果未能解决你的问题,请参考以下文章