資料庫(SQL)兩表關聯欄位模糊
最近發現一個比較噁心的問題,由於業務或是其他不可說的原因(各位讀者自行腦補)的問題導致原有儲存的資料發生變動;與現有資料有差別,如原有的資料名稱發生變動,但是還要對資料進行匹配(,此時你的內心如羊駝狂奔而過,唉,還是要處理的呀),來看資料,
先介紹一下表,
原表名/新表名 | 欄位名及其解釋 | 註釋 | |||||||||||||||
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來執行。好了就是這樣了!