mysql - 使用连接更新以填补 MySQL 中的缺失值
问题描述
我编写了这些行来填充邮政编码列中的空值。它应该根据位置列的值填写邮政编码列。
当我执行它时,它会无限期地运行并且没有给我想要的结果。有人可以告诉我我做错了什么吗?或者我可以使用什么其他方法来获得所需的结果?
UPDATE nycaccidents2020 a
JOIN nycaccidents2020 b
USING(location)
SET a.`zip code` = b.`zip code`
WHERE a.`zip code` IS NULL AND b.`zip code` IS NOT NULL;
样品表:
地点 | 邮政编码 |
---|---|
点 (-73.946556 40.8165) | 10030 |
点 (-73.83376 40.8921) | 10466 |
点 (-73.919914 40.6905) | 11221 |
点 (-73.946556 40.8165) | 无效的 |
解决方案
该查询在技术上是正确的,但它可能会很慢,因为有许多行具有相同的位置,并且它正在与所有行连接,从而产生很大的叉积。您可以通过加入一个子查询来改进它,该子查询将它们减少到每个位置一行。
UPDATE nycaccidents2020 AS a
JOIN (
SELECT DISTINCT location, `zip code`
FROM nyaccidents2020
WHERE `zip code` IS NOT NULL
) AS b USING (location)
SET a.`zip code` = b.`zip code`
WHERE a.`zip code` IS NULL
这也可能存在性能问题,因为子查询没有被索引。您可以通过创建一个临时表并对其进行索引来改进它。
CREATE TEMPORARY TABLE locations AS
SELECT DISTINCT location, `zip code`
FROM nyaccidents2020
WHERE `zip code` IS NOT NULL;
ALTER TABLE locations ADD INDEX (location);
UPDATE nycaccidents2020 a
JOIN locations b USING(location)
SET a.`zip code` = b.`zip code`
WHERE a.`zip code` IS NULL
通过规范化数据可以避免整个问题。您可以有一个包含位置和邮政编码的单独表,并且事故表可以使用引用该表的外键。
推荐阅读
- sql - 在 SQL 中编写或替换双 for 循环(表遍历另一个表遍历)的有效方法
- postgresql - 将 TableQuery 对象作为参数传递会在 Slick/Scala 中导致奇怪的类型错误,但在注入时不会
- python - 如何使用 Python VLC 创建多个播放器并在它们上具有不同的卷?
- android - Stripe future payment getting error 版本 16.1.1 没有这样的 SetUpIntent
- python - 我们可以使用 Discord.py 重写来获取 Discord 用户的延迟(ping)吗?
- azure-devops - 如何分配 Azure DevOps 项目管理员
- scala - Scala 中的编程示例混淆(清单 3.5,创建可变和不可变集)
- c# - 根据使用 System.IO.Ionic.Zlib.DotNetZip.dll 压缩的 db 列大小获取未压缩文件的大小
- python - 从用户想要查看的 csv 文件中打印特定信息
- android - 如何在 Android 中将背景设置为 MenuItem onPrepareMenuOptions