对于火花吹
假设我有一个像下面这样的表
| Header 1 | Header 2 | Header 3
--------------------------------------------------------------------------------------
| id1 | detail1 | <a@test.com> , <b@test.com> , <c@test.com> , <d@test.com>
我如何在SQL上基于子字符串email在尖括号内,使它看起来像下面的一个。
| Header 1 | Header 2 | Header 3. |
-------------------------------------------
| id1 | detail1 | a@test.com |
| id1 | detail1 | b@test.com |
| id1 | detail1 | c@test.com |
| id1 | detail1 | d@test.com |
使用regexp_extract_all
和explode
就可以了。
select `Header 1`, `Header 2`, explode(regexp_extract_all(`Header 3`, '<(.+?)>')) as `Header 3` from table
+--------+--------+----------+
|Header 1|Header 2|Header 3 |
+--------+--------+----------+
|id1 |detail1 |a@test.com|
|id1 |detail1 |b@test.com|
|id1 |detail1 |c@test.com|
|id1 |detail1 |d@test.com|
+--------+--------+----------+
请注意regexp_extract_all
自3.1.0
版本以来添加到spark。
对于火花吹3.1.0
这可以用split
完成,有点肮脏的hack。但是策略和结果是一样的。
select `Header 1`, `Header 2`, explode(array_remove(split(`Header 3`, '[<>,\s]+'), '')) as `Header 3` from table
它的作用是对分隔符进行正则匹配,并将字符串拆分为数组。它还需要一个array_remove
函数调用来删除不需要的空字符串。
解释对于regexp_extract_all
,我们使用模式<(.+?)>
将尖括号内的所有字符串提取到如下数组中
['a@test.com', 'b@test.com', 'c@test.com']
模式(.+?)
在这里
.
匹配1字符;+
是.
的量词,查找一个或无限匹配;?
是一个非贪婪修饰符,使匹配尽快停止;- 括号将带in尖括号的模式作为匹配组,以便我们稍后可以从组中提取;
现在使用explode
,我们可以将数组的元素分成多行,从而得到上面的结果。