如何在SQL列中的字符串内爆炸子字符串



假设我有一个像下面这样的表

| 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_allexplode就可以了。

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_all3.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,我们可以将数组的元素分成多行,从而得到上面的结果。

最新更新