验证从一个 table 到另一个 MySQL 中的字段
Validate fields from one table to another in MySQL
问题:
我有 1 table 大约 5000 行 称为 imported_cities
我有 1 table 大约 800 000 行 称为 postal_codes 包含邮政编码城市
我需要根据城市名称及其所在省份根据邮政编码table中的城市验证每个不同的城市。请参阅下面的 table 结构。
如果它们完全匹配(是的,完全匹配。其余城市是手动验证的)我必须更新imported_city上的一列 和
将imported_cities的城市和postal_codes的城市(并排)输入第三个table 称为 imported_cities_equiv
我试过的:
将索引添加到 tables 并在下面进行查询。 需要永远... :(
explain SELECT DISTINCT ic.destinationCity, pc.city FROM (imported_cities ic, postalcodes pc)
WHERE LOWER(ic.destinationCity) = LOWER(pc.city)
结果
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE ip index NULL company_city 478 NULL 4221 Using index; Using temporary
1 SIMPLE pc index NULL city_prov 160 NULL 765407 Using where; Using index; Using join buffer (Block...
--
-- Table table postalcodes
的结构
CREATE TABLE IF NOT EXISTS `postalcodes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`code` varchar(11) NOT NULL,
`city` varchar(50) NOT NULL,
`province` varchar(50) NOT NULL,
`provinceISO` varchar(2) NOT NULL,
`latitude` decimal(17,13) NOT NULL,
`longitude` decimal(17,13) NOT NULL,
PRIMARY KEY (`id`),
KEY `code` (`code`),
KEY `city_prov` (`city`,`provinceISO`)
--
-- Table table imported_cities
的结构
CREATE TABLE IF NOT EXISTS `imported_cities` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`companyName` varchar(30) CHARACTER SET utf8 NOT NULL,
`destinationCity` varchar(128) CHARACTER SET utf8 NOT NULL,
`destinationProvince` varchar(20) CHARACTER SET utf8 NOT NULL,
`equivCity` varchar(128) CHARACTER SET utf8 DEFAULT NULL,
`minAmount` decimal(6,2) NOT NULL
PRIMARY KEY (`id`),
KEY `company_city` (`companyName`,`destinationCity`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=7933 ;
--
-- Table table imported_cities_equiv
的结构
CREATE TABLE IF NOT EXISTS `imported_cities_equiv` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`imported_city` varchar(128) CHARACTER SET utf8 NOT NULL,
`pc_city` varchar(128) CHARACTER SET utf8 NOT NULL,
`province` varchar(20) CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=149 ;
如有任何帮助或建议,我们将不胜感激。谢谢。
您要获取信息的查询是:
SELECT ip.*, (pc.city is not null) as exact match
FROM imported_prices ip left join
postalcodes pc
on LOWER(ip.destinationCity) = LOWER(pc.city) and
lower(ip.province) = lower(pc.province);
然而,这将有非常糟糕的表现。摆脱 lower()
会有所帮助:
SELECT ip.*, (pc.city is not null) as exact match
FROM imported_prices ip left join
postalcodes pc
on(ip.destinationCity) =(pc.city) and
(ip.province) = (pc.province);
因为这样您就可以在 postalcodes(city, province)
上添加索引。
如果您不能使用删除 lower()
,则更改 table 以添加新列并将小写值放入这些列中。然后在新列上建立索引并在连接中使用它们。
谢谢大家给我指明了正确的方向。
根据您的建议进行了一些更改:
- 在 destinationCity 和 destinationProvince 列的 imported_cities table 上添加了索引
- 在城市和省份 ISO 列table 上添加了邮政编码索引
- JOIN 子句只有一侧大写,因为字段 ic.destinationCity 已经是大写
- 按省份限制 WHERE 性能查询
最后的SQL是:
SELECT DISTINCT pc.city, pc.provinceISO
FROM postalcodes pc
LEFT JOIN imported_cities ic
ON upper(pc.city) = ic.destinationCity AND
pc.provinceISO = ic.destinationProvince
WHERE ic.destinationProvince = 'QC';
和解释
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE pc ref province province 8 const 278115 Using index condition; Using temporary
1 SIMPLE ip ref destinationCity,destinationProvince destinationCity 386 func 1 Using index condition; Using where; Distinct
展望未来,我现在可以在 PHP 上构建 INSERT 查询,并进行一个 INSERT 查询以在 3rd table 上插入所有等效城市。谢谢大家
问题:
我有 1 table 大约 5000 行 称为 imported_cities
我有 1 table 大约 800 000 行 称为 postal_codes 包含邮政编码城市
我需要根据城市名称及其所在省份根据邮政编码table中的城市验证每个不同的城市。请参阅下面的 table 结构。
如果它们完全匹配(是的,完全匹配。其余城市是手动验证的)我必须更新imported_city上的一列 和 将imported_cities的城市和postal_codes的城市(并排)输入第三个table 称为 imported_cities_equiv
我试过的: 将索引添加到 tables 并在下面进行查询。 需要永远... :(
explain SELECT DISTINCT ic.destinationCity, pc.city FROM (imported_cities ic, postalcodes pc)
WHERE LOWER(ic.destinationCity) = LOWER(pc.city)
结果
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE ip index NULL company_city 478 NULL 4221 Using index; Using temporary
1 SIMPLE pc index NULL city_prov 160 NULL 765407 Using where; Using index; Using join buffer (Block...
--
-- Table table postalcodes
的结构
CREATE TABLE IF NOT EXISTS `postalcodes` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`code` varchar(11) NOT NULL,
`city` varchar(50) NOT NULL,
`province` varchar(50) NOT NULL,
`provinceISO` varchar(2) NOT NULL,
`latitude` decimal(17,13) NOT NULL,
`longitude` decimal(17,13) NOT NULL,
PRIMARY KEY (`id`),
KEY `code` (`code`),
KEY `city_prov` (`city`,`provinceISO`)
--
-- Table table imported_cities
的结构
CREATE TABLE IF NOT EXISTS `imported_cities` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`companyName` varchar(30) CHARACTER SET utf8 NOT NULL,
`destinationCity` varchar(128) CHARACTER SET utf8 NOT NULL,
`destinationProvince` varchar(20) CHARACTER SET utf8 NOT NULL,
`equivCity` varchar(128) CHARACTER SET utf8 DEFAULT NULL,
`minAmount` decimal(6,2) NOT NULL
PRIMARY KEY (`id`),
KEY `company_city` (`companyName`,`destinationCity`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=7933 ;
--
-- Table table imported_cities_equiv
的结构
CREATE TABLE IF NOT EXISTS `imported_cities_equiv` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`imported_city` varchar(128) CHARACTER SET utf8 NOT NULL,
`pc_city` varchar(128) CHARACTER SET utf8 NOT NULL,
`province` varchar(20) CHARACTER SET utf8 NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=149 ;
如有任何帮助或建议,我们将不胜感激。谢谢。
您要获取信息的查询是:
SELECT ip.*, (pc.city is not null) as exact match
FROM imported_prices ip left join
postalcodes pc
on LOWER(ip.destinationCity) = LOWER(pc.city) and
lower(ip.province) = lower(pc.province);
然而,这将有非常糟糕的表现。摆脱 lower()
会有所帮助:
SELECT ip.*, (pc.city is not null) as exact match
FROM imported_prices ip left join
postalcodes pc
on(ip.destinationCity) =(pc.city) and
(ip.province) = (pc.province);
因为这样您就可以在 postalcodes(city, province)
上添加索引。
如果您不能使用删除 lower()
,则更改 table 以添加新列并将小写值放入这些列中。然后在新列上建立索引并在连接中使用它们。
谢谢大家给我指明了正确的方向。
根据您的建议进行了一些更改:
- 在 destinationCity 和 destinationProvince 列的 imported_cities table 上添加了索引
- 在城市和省份 ISO 列table 上添加了邮政编码索引
- JOIN 子句只有一侧大写,因为字段 ic.destinationCity 已经是大写
- 按省份限制 WHERE 性能查询
最后的SQL是:
SELECT DISTINCT pc.city, pc.provinceISO
FROM postalcodes pc
LEFT JOIN imported_cities ic
ON upper(pc.city) = ic.destinationCity AND
pc.provinceISO = ic.destinationProvince
WHERE ic.destinationProvince = 'QC';
和解释
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE pc ref province province 8 const 278115 Using index condition; Using temporary
1 SIMPLE ip ref destinationCity,destinationProvince destinationCity 386 func 1 Using index condition; Using where; Distinct
展望未来,我现在可以在 PHP 上构建 INSERT 查询,并进行一个 INSERT 查询以在 3rd table 上插入所有等效城市。谢谢大家