我會放在一起的表的一個更正式的定義開始:
warehouse:
warehouse_id,
warehouse_product_id,
product_brand,
product_name,
local_id
在這裏我使用local_id作爲一個外鍵的「模式」表 - 但要避免進一步的混亂,我會稱之爲'本地'
local:
id,
product_brand,
product_name
看起來您所描述的表格「產品」是多餘的。
很明顯,直到數據被交叉引用,local_id將爲空。但是,填充後不會有變化,並給予warehouse_id,帶和產品,你可以很容易地找到你的本地描述:
SELECT local.*
FROM local, warehouse
WHERE local.id=warehouse.local_id
AND warehouse.product_brand=local.product_brand
AND warehouse_id=_____
AND warehouse.product_brand=____
AND warehouse.product_name=____
因此,所有你需要做的是填寫的聯繫。 Soundex是一個相當粗糙的工具 - 更好的解決方案是Levenstein distance algorithm。有一個mysql implementation here
給定一組需要被填充在倉庫表中的行:
SELECT w.*
FROM warehouse w
WHERE w.local_id IS NULL;
...每一行標識爲(使用從以前的查詢中值的最佳匹配爲w 。*)....
SELECT local.id
FROM local
WHERE local.product_brand=w.product_brand
ORDER BY levenstein(local.product_name, w.product_name) ASC
LIMIT 0,1
但是,即使2個字符串完全不同,這也會找到最佳匹配!因此......
SELECT local.id
FROM local
WHERE local.product_brand=w.product_brand
AND levenstein(local.product_name, w.product_name)<
(IF LENGTH(local.product_name)<LENGTH(w.product_name),
LENGTH(local.product_name), LENGTH(w.product_name))/2
ORDER BY levenstein(local.product_name, w.product_name) ASC
LIMIT 0,1
......需要至少一半的字符串匹配。
因此,這可以在一個單一的更新語句來實現:
UPDATE warehouse w
SET local_id=(
SELECT local.id
FROM local
WHERE local.product_brand=w.product_brand
AND levenstein(local.product_name, w.product_name)<
(IF LENGTH(local.product_name)<LENGTH(w.product_name),
LENGTH(local.product_name), LENGTH(w.product_name))/2
ORDER BY levenstein(local.product_name, w.product_name) ASC
LIMIT 0,1
)
WHERE local_id IS NULL;
是一種不可能的品牌`BMW`區分VS產品名稱爲'bmw` ... – ajreal 2011-06-21 16:04:43