我会放在一起的表的一个更正式的定义开始:
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