最近发现一个比较恶心的问题,由于业务或是其他不可说的原因(各位读者自行脑补)的问题导致原有存储的数据发生变动;与现有数据有差别,如原有的数据名称发生变动,但是还要对数据进行匹配(,此时你的内心如羊驼狂奔而过,唉,还是要处理的呀),来看数据,
先介绍一下表,
原表名/新表名 | 字段名及其解释 | 注释 | |||||||||||||||
z_good |
|
旧表 | |||||||||||||||
z_good_new |
|
新表 |
旧表,z_good,数据、条数只是事例
新表,z_good_new,数据、条数只是事例
发现什么没有,z_good的name列与z_good_new的mc列的数据相似,但是不完全一致(只有名称是类似的,上图的数据是我列举的,事实的备注也是不一致的)。这就是我上面说的名字发生了变动,需求是要把新名字放到旧表的newmc列中(也就是z_good_new的mc列 一 一对应到newmc列,前提肯定是相似的才能放入了)
有人说我手动处理,我感觉你疯了(),这只是列举的10条数据,当然可以手动处理。如果两表各有1万条数据呢、10万条呢、100万条呢 你还手动处理,你疯了吧,没发烧吧怎么开始说胡话了()手动处理,到你挂的时候你能处理完就不错了()!
所以,办法来了,两表关联查询,你会这么写
,完蛋,只有一条数据匹配到了,其他的都报废了。你可能会说:没办法了,剩下的手动处理吧。手动处理你就废了,彻底废了。原因就出在b.mc=a.name,因为数据是严格匹配的,例如"2020怒晴湘西"和"怒晴湘西"从数据层面看确实不是一个东西,但是人为处理知道这两个数据是一回事,更何况"2020怒晴湘西"他本身和"怒晴湘西"就是一回事,只是换了个名字升级了,那我怎样处理才能让让他更多的匹配到,减少手动处理的工作量呢
,别慌,稳住。看完我这个或许还有救,就算要手动处理,我们也要减少手动处理的工作量,要不“会死人的”,真的“会死人的”
mysql的处理办法:
sql:
select a.id,a.`name`,b.newid,b.mc
from z_good a
left join z_good_new b on instr(a.`name`,b.mc)>0
发现没有匹配到的数据变多了,只有少部分的数据没有匹配到,这是时候再手动处理。发现了吧这次没写on b.mc=a.name而是on instr(a.`name`,b.mc)>0。
MySql的instr函数:
INSTR(STR,SUBSTR) 在一个字符串(STR)中搜索指定的字符(SUBSTR),返回发现指定的字符的位置(INDEX);
STR 被搜索的字符串
SUBSTR 希望搜索的字符串
结论:在字符串STR里面,字符串SUBSTR出现的第一个位置(INDEX),INDEX是从1开始计算,如果没有找到就直接返回0,没有返回负数的情况。
关于MySql的instr函数的解释太多了,一百度一大堆,我就不做解释了。
SQLserver
/**两个表 字段模糊匹配**//**使用like进行查询 如何进行匹配**/
select * from table_A a,table_B b where b.name like convert(nvarchar(200),'%'+a.name +'%') ——这个没试过,网上看到的,看情况应该是可以的。
PGSQL
sql:
select a.id,a.name,b.newid,b.mc from z_good a left join z_good_new b on a.name like ('%'||b.mc||'%'); |
把没有匹配的也展示出来了,看到没有匹配的数据只是少部分,那就只能手动处理了,最起码比原来好多了 |
sql:
select a.id,a.name,b.newid,b.mc from z_good a,z_good_new b where a.name like ('%'||b.mc||'%'); |
只展示了相互匹配到的数据,与inner join效果一致。没有匹配的数据去原数据表查看,结果只是少部分。那就手动处理,最起码比原来好多了 |
其他数据库一般都有自己的函数或者写法那要自己找下了。具体sql怎么写,还要看先下数据、分析下,从中找出手动处理数据最少的SQL来执行。好了就是这样了!