搜索

sqlserver拆分地址省市县

发表于 2026-10-17 05:57:08 来源:烟消火灭网

上周帮一个做电商的分地朋友处理订单数据,他发来一张用户表,址省地址字段全是市县“浙江省杭州市余杭区文一西路969号”这种连在一起的字符串。他需要按省、分地市、址省县拆开做区域分析。市县我打开SQL Server,分地写了三行代码,址省问题解决。市县他盯着屏幕看了半天,分地说原来这么简单。址省

拆分地址这件事,市县核心就一个函数:CHARINDEX。分地它返回某个字符在字符串中的址省位置。省、市县市、县这三个字就是天然的分隔符。找到“省”的位置,它前面的就是省名;找到“市”的位置,省和市之间的就是市名;找到“县”或“区”的位置,市和县之间的就是县名。逻辑就这么直白。

先看具体写法。假设表名是UserAddress,地址字段叫FullAddress。提取省份:

SELECT LEFT(FullAddress, CHARINDEX('省', FullAddress)) AS Province FROM UserAddress;

CHARINDEX('省', FullAddress)返回“省”字的位置,LEFT从左边截取到这个位置。注意这里包含了“省”字本身。如果不需要“省”字,就减一:LEFT(FullAddress, CHARINDEX('省', FullAddress) - 1)。

提取城市稍微绕一点。需要从“省”之后开始找“市”:

SELECT SUBSTRING( FullAddress, CHARINDEX('省', FullAddress) + 1, CHARINDEX('市', FullAddress) - CHARINDEX('省', FullAddress) ) AS City FROM UserAddress;

SUBSTRING三个参数:原字符串、起始位置、截取长度。起始位置是“省”的位置加一,长度是“市”的位置减去“省”的位置。这样截出来的是“杭州市”三个字,含“市”。

县区同理。起始位置是“市”的位置加一,长度是“县”或“区”的位置减去“市”的位置。但问题来了——有些地址是“县”,有些是“区”。比如“浙江省杭州市余杭区”和“浙江省湖州市德清县”。得同时处理两种情况。

我通常用CASE WHEN判断:

SELECT CASE WHEN CHARINDEX('县', FullAddress) > 0 THEN SUBSTRING(FullAddress, CHARINDEX('市', FullAddress) + 1, CHARINDEX('县', FullAddress) - CHARINDEX('市', FullAddress)) WHEN CHARINDEX('区', FullAddress) > 0 THEN SUBSTRING(FullAddress, CHARINDEX('市', FullAddress) + 1, CHARINDEX('区', FullAddress) - CHARINDEX('市', FullAddress)) ELSE NULL END AS District FROM UserAddress;

这里有个细节:CHARINDEX找不到目标字符时返回0。所以判断条件用> 0,而不是IS NOT NULL。我见过有人写IS NOT NULL,结果所有行都返回0,查了半天才发现问题。

直辖市是另一个坑。上海市、北京市的地址往往写成“上海市浦东新区张江镇”,没有“省”字。上面的省份提取逻辑会返回空字符串。处理办法是单独判断:如果地址以“上海市”开头,省份就是“上海市”。或者更通用一点,用CHARINDEX('省')为0时,取前三个字符作为省份。但“内蒙古自治区”这种又不一样。实际项目中,我建议先跑一遍数据,看看地址格式到底有几种模式,再针对性写逻辑。

还有一种情况:地址里根本没有“省”和“市”,比如“余杭区文一西路969号”。这时候所有CHARINDEX都返回0,截取结果全是空。这类数据只能人工处理或者标记为异常。我朋友那张表里有大约3%的地址是这种格式,最后单独导出来让客服补全了。

性能方面,CHARINDEX和SUBSTRING都是标量函数,在SELECT里逐行计算。数据量小无所谓,几百万行的话会慢。可以考虑用计算列加索引,或者干脆在ETL阶段用SSIS处理。我试过在500万行的表上跑,没建索引,大概用了40秒。能接受,但不算快。

最后说个取巧的办法。如果地址格式非常规整,比如永远是“省+市+区+详细地址”,可以用PARSENAME配合替换。把“省”“市”“区”替换成点号,然后用PARSENAME按点号拆分。但PARSENAME最多只支持四部分,而且遇到详细地址里有点号就乱了。我还是更倾向CHARINDEX方案,虽然代码长一点,但可控。

朋友后来把拆分好的数据导进BI工具,做了个热力图,发现浙江订单集中在杭州余杭区。他跟我说,早知道地址拆分这么简单,就不用雇实习生手动整理三天了。我回他:你早该请我吃饭。

随机为您推荐
友情链接
版权声明:本站资源均来自互联网,如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

Copyright © 2016 Powered by sqlserver拆分地址省市县,烟消火灭网   sitemap

回顶部