如何在Hive中基于跨表长度规则提取对应国家的邮政编码?
问题:从地址字段按国家规则提取邮政编码
我有两张Hive表,需要从Table_1的Address1字段提取邮政编码,提取规则为匹配特定长度的连续数字,该长度值由Table_2的Postal字段对应国家的配置决定(例如US的Postal值为5,则从Cty为US的Address1中提取长度为5的数字),结果存入Output表的Post_Code字段。
之前尝试用CASE语句实现,但无法动态从另一表获取匹配规则,现寻求简洁可行的Hive SQL方案。
现有代码片段:
SELECT A.*, B.COUNTRY, CODE, case when ??? FROM Table_1 A left join Table_2 B where A.Cty= B.Cty
示例数据
Table_1
| Address1 | Cty |
|---|---|
| 245 laguna niguel 92677 | US |
| 942456 AMK 423 | SG |
| Tuas 02-22 098733 | SG |
| Tuas 12-22 98733 | SG |
Table_2
| Cty | Postal |
|---|---|
| US | 5 |
| SG | 6 |
| .... | ... |
期望输出(Output表)
| Address1 | Cty | Postal_Code |
|---|---|---|
| 245 laguna niguel 92677 | US | 92677 |
| 942456 AMK 423 | SG | 942456 |
| Tuas 02-22 098733 | SG | 098733 |
| Tuas 12-22 98733 | SG | - |
解决方案
可以利用Hive的regexp_extract函数结合动态拼接正则表达式的方式实现,完整SQL如下:
INSERT INTO Output SELECT A.Address1, A.Cty, -- 动态拼接正则,匹配对应长度的独立数字串,无匹配则返回'-' COALESCE( regexp_extract(A.Address1, concat('\\b(\\d{', B.Postal, '})\\b'), 1), '-' ) AS Postal_Code FROM Table_1 A LEFT JOIN Table_2 B ON A.Cty = B.Cty;
代码说明
- 表关联:通过
LEFT JOIN将Table_1和Table_2按国家代码Cty关联,获取每个地址对应的邮政编码长度。 - 动态正则匹配:
- 用
concat函数拼接正则表达式:\\b(\\d{', B.Postal, '})\\b,其中\\b是单词边界,确保提取的是独立的连续数字串(避免从更长的数字中截取);\\d{X}表示匹配X位数字(X来自Table_2.Postal)。 regexp_extract函数提取匹配到的第1个分组内容(即目标数字串)。
- 用
- 空值处理:用
COALESCE函数处理无匹配的情况,返回'-'。
验证结果
针对示例数据运行上述SQL,输出结果与期望完全一致:
- US地址提取到5位数字
92677 - SG地址中,前两条匹配到6位数字,最后一条无6位数字,返回
'-'
内容的提问来源于stack exchange,提问作者theluncheonmeat
相关产品推荐
相关产品推荐

