SparkSQL|字符串函数

  • 字符串长度函数:length

语法: length(string A)

返回值: int

说明:返回字符串A的长度

举例:

select length('abcedfg') from lxw_dual;
7

  • 字符串反转函数:reverse

语法: reverse(string A)

返回值: string

说明:返回字符串A的反转结果

举例:

select reverse(abcedfg’) from lxw_dual;
gfdecba

  • 字符串连接函数:concat

语法: concat(string A, string B…)

返回值: string

说明:返回输入字符串连接后的结果,支持任意个输入字符串

举例:

select concat(‘abc’,'def’,'gh’) from lxw_dual;
abcdefgh

加百分号
concat(round(100*sum(coalesce(a.eleme_subsidy_amt,0))/sum(coalesce(a.order_total_amt,0)),2),'%') eleme_subsidy_rate

  • 带分隔符字符串连接函数:concat_ws

语法: concat_ws(string SEP, string A, string B…)

返回值: string

说明:返回输入字符串连接后的结果,SEP表示各个字符串间的分隔符

举例:

select concat_ws(',','abc','def','gh') from lxw_dual;
abc,def,gh

  • 字符串截取函数:substr,substring

语法: substr(string A, int start),substring(string A, int start)

返回值: string

说明:返回字符串A从start位置到结尾的字符串

举例:

select substr('abcde',3) from lxw_dual;
cde
select substring('abcde',3) from lxw_dual;
cde
selectsubstr('abcde',-1) from lxw_dual;  (和ORACLE相同)
e

  • 字符串截取函数:substr,substring

语法: substr(string A, int start, int len),substring(string A, intstart, int len)

返回值: string

说明:返回字符串A从start位置开始,长度为len的字符串

举例:

select substr('abcde',3,2) from lxw_dual;
cd
select substring('abcde',3,2) from lxw_dual;
cd
hive>select substring('abcde',-2,2) from lxw_dual;
de

  • 字符串转大写函数:upper,ucase

语法: upper(string A) ucase(string A)

返回值: string

说明:返回字符串A的大写格式

举例:

select upper('abSEd') from lxw_dual;
ABSED
select ucase('abSEd') from lxw_dual;
ABSED

  • 字符串转小写函数:lower,lcase

语法: lower(string A) lcase(string A)

返回值: string

说明:返回字符串A的小写格式

举例:

select lower('abSEd') from lxw_dual;
absed
select lcase('abSEd') from lxw_dual;
absed

  • 去空格函数:trim

语法: trim(string A)

返回值: string

说明:去除字符串两边的空格

举例:

select trim(' abc ') from lxw_dual;
abc

  • 左边去空格函数:ltrim

语法: ltrim(string A)

返回值: string

说明:去除字符串左边的空格

举例:

select ltrim(' abc ') from lxw_dual;
abc

  • 右边去空格函数:rtrim

语法: rtrim(string A)

返回值: string

说明:去除字符串右边的空格

举例:

select rtrim(' abc ') from lxw_dual;
abc

  • 正则表达式替换函数:regexp_replace

语法: regexp_replace(string A, string B, string C)

返回值: string

说明:将字符串A中的符合java正则表达式B的部分替换为C。注意,在有些情况下要使用转义字符,类似oracle中的regexp_replace函数。

=================================================================

正则表达式

1. 基本

代码       说明
.       匹配除换行符以外的任意字符
\w      匹配字母或数字或下划线或汉字
\s      匹配任意的空白符
\d      匹配数字
\b      匹配单词的开始或结束
^       匹配字符串的开始
$       匹配字符串的结束

*       重复零次或更多次
+       重复一次或更多次
?       重复零次或一次
{n}     重复n次
{n,}    重复n次或更多次
{n,m}   重复n到m次

2. 字符转义

这时你就得使用\来取消这些字符的特殊意义。因此,你应该使用\.和\*。当然,要查找\本身,你也得用\\.

3. 字符集合

如果你想匹配没有预定义元字符的字符集合(比如元 音字母a,e,i,o,u),在方括号里列出它们就行了,像[aeiou]就匹配任何一个英文元音字母,[.?!]匹配标点符号(.或?或!)

我们也可以轻松地指定一个字符范围,像[0-9]代 表的含意与\d就是完全一致的:一位数字; 同理[a-z0-9A-Z_]也完全等同于\w(如果只考虑英文的话)

下面是一个更复杂的表达式:\(?0\d{2}[) -]?\d{8}。

“(”和“)”也是元字符,所以在这里需要使用转义。

这个表达式可以匹配几种格式的电话号码,像(010)88886666,或022-22334455, 或02912345678等。

我们对它进行一些分析吧:首先是一个转义字符\(,它能出现0次或1次(?),然后是一个0,后面跟着2个数字(\d{2}),然后是)或-或空格中 的一个,它出现1次或不出现(?),最后是8个数字(\d{8})

=================================================================

regexp_replace(1,2,3,4,5,6)

6个参数

第一个是输入的字符串

第二个是正则表达式

第三个是替换的字符

第四个是标识从第几个字符开始正则表达式匹配。(默认为1)

第五个是标识第几个匹配组。(默认为全部都替换掉)

第六个是是取值范围:

i:大小写不敏感;

c:大小写敏感;

n:点号 . 不匹配换行符号;

m:多行模式;

x:扩展模式,忽略正则表达式中的空白字符。

举例:

    select regexp_replace('foobar', 'oo|ar', '') from lxw_dual;
    select regexp_replace(regexp_replace(event,'有借:',''),'详情页','')
    select regexp_replace(regexp_replace(regexp_replace(event, '[a-z]*', '') ,'-',''),'[0-9]*','')-- 去除字符串中的数字、字母、横杠(此处相当于只保留汉字)
    select regexp_replace('有借fhsdhfj56847365','[\\u4e00-\\u9fa5]+','') -- 去掉中文

select regexp_replace(regexp_replace('(安德路店)东北大陷水饺(安德路店)','[\\(|(](.*?)[\\)|)]',''),' ','')
select regexp_replace(regexp_replace('【清真】杨铭宇黄焖鸡米饭(福田店)','[\\(|(|【](.*?)[\\)|)|】]',''),' ','')

  • 正则表达式解析函数:regexp_extract

语法: regexp_extract(string subject, string pattern, int index)

返回值: string

说明:将字符串subject按照pattern正则表达式的规则拆分,返回index指定的字符。

第一参数: 要处理的字段

第二参数: 需要匹配的正则表达式

第三个参数:

0是显示与之匹配的整个字符串

1 是显示第一个括号里面的

2 是显示第二个括号里面的字段…

举例:

    select regexp_extract('foothebar', 'foo(.*?)(bar)', 1) fromlxw_dual;
    
    the
    
    select regexp_extract('foothebar', 'foo(.*?)(bar)', 2) fromlxw_dual;
    
    bar
    
    select regexp_extract('foothebar', 'foo(.*?)(bar)', 0) fromlxw_dual;
    
    foothebar
    
    select regexp_extract('有借:钱有路详情页','有借:(.*)详情页',1) ^ 表示开头,$表示结尾,.表示 任意字符 ,* 表示匹配模式里面任意多个

    select regexp_extract('有借123','[\\u4e00-\\u9fa5]+',0) --只取中文
    有借
    select regexp_replace('有借123','[\\u4e00-\\u9fa5]+','')--去掉中文
    123

  • 使用presto(hive/spark不行)自带的 REGEXP_LIKE()可替代多个like 查询:
SELECT  * FROM 
dw_sia.dw_sia_restaurant_info 
	where dt=get_date(-1) 
and
 regexp_like(brand_name, '周|粥|巨|龙')

  • URL解析函数:parse_url

语法: parse_url(string urlString, string partToExtract [, stringkeyToExtract])

返回值: string

说明:返回URL中指定的部分。partToExtract的有效值为:HOST, PATH, QUERY, REF, PROTOCOL, AUTHORITY, FILE, and USERINFO.

举例:

select parse_url('http://facebook.com/path1/p.php?k1=v1&k2=v2Ref1', 'HOST') fromlxw_dual;
facebook.com
select parse_url('http://facebook.com/path1/p.php?k1=v1&k2=v2Ref1', 'QUERY','k1') from lxw_dual;
v1

  • json解析函数:get_json_object

语法: get_json_object(string json_string, string path)

返回值: string

说明:解析json的字符串json_string,返回path指定的内容。如果输入的json字符串无效,那么返回NULL。

举例:

    test_table_1.request_text={"channel":"e_business","idCard":"350321990******87","name":"张三","phone":"13758****17"}
    
    select request_text,get_json_object(request_text,'$.idCard') as idCard from auth_mobp2p.test_table_1;
    
    hive>350321990******87


    select get_json_object('{"store":
    
    >  {"fruit":\[{"weight":8,"type":"apple"},{"weight":9,"type":"pear"}],
    
    >   "bicycle":{"price":19.95,"color":"red"}
    
    >   },
    
    > "email":"amy@only_for_json_udf_test.net",
    
    >  "owner":"amy"
    
    > }
    
    > ','$.owner') from lxw_dual;
    
    amy

parse_json_object(profile_json, '$.base.gender')
get_json_object(get_json_object(price_rule_value,'$.values'),'$.ELEME_PRICE') 


json格式的内容,行转列:

select 
	t.user_id,
	split(category_prefers_1,":") [0] as name,
	split(category_prefers_1,":") [1] as point
from
	(select 
		t.user_id,
		category_prefers_1
	from
		(select 
			user_id,
			split(regexp_replace(regexp_replace(parse_json_object(profile_json, '$.rec.category_prefer'),'[\\{|\\}|\\"|\\"]',''),' ',''),",") category_prefers
		from 
			dm.dm_ups_user_info
		where 
			dt=get_date(-1)) t lateral view explode(t.category_prefers) adtable as category_prefers_1) t;

  • 空格字符串函数:space

语法: space(int n)

返回值: string

说明:返回长度为n的字符串

举例:

select space(10) from lxw_dual;

select length(space(10)) from lxw_dual;

10

  • 重复字符串函数:repeat

语法: repeat(string str, int n)

返回值: string

说明:返回重复n次后的str字符串

举例:

select repeat('abc',5) from lxw_dual;

abcabcabcabcabc

  • 首字符ascii函数:ascii

语法: ascii(string str)

返回值: int

说明:返回字符串str第一个字符的ascii码

举例:

select ascii('abcde') from lxw_dual;

97

  • 左补足函数:lpad

语法: lpad(string str, int len, string pad)

返回值: string

说明:将str进行用pad进行左补足到len位

举例:

select lpad('abc',10,'td') from lxw_dual;

tdtdtdtabc

注意:与GP,ORACLE不同,pad 不能默认

  • 右补足函数:rpad

语法: rpad(string str, int len, string pad)

返回值: string

说明:将str进行用pad进行右补足到len位

举例:

select rpad('abc',10,'td') from lxw_dual;

abctdtdtdt

  • 分割字符串函数: split

语法: split(string str, stringpat)

返回值: array

说明: 按照pat字符串分割str,会返回分割后的字符串数组

举例:

select split('abtcdtef','t') from lxw_dual;

["ab","cd","ef"]

a.基本用法:

例1:
split('a,b,c,d',',')
得到的结果:
["a","b","c","d"]

b.截取字符串中的某个值:

当然,我们也可以指定取结果数组中的某一项

例2:
split('a,b,c,d',',')[0]
得到的结果:
a

c.特殊字符的处理:

特殊分割符号

regex 为字符串匹配的参数,所以遇到特殊字符的时候需要做特殊的处理

例3:  "." 点
split('192.168.0.1','.')
得到的结果:
[]
正确的写法:
split('192.168.0.1','\\.')
得到的结果:
["192","168","0","1"]

需要注意的是:

当然当split包含在 “” 之中时 需要加4个\

如 hive -e “…. split(‘192.168.0.1′,’\\\\.’) … ” 不然得到的值是null

同样的 | 等特殊符号也需要做类似 处理。

  • 集合查找函数:find_in_set

语法: find_in_set(string str, string strList)

返回值: int

说明: 返回str在strlist第一次出现的位置,strlist是用逗号分割的字符串。如果没有找该str字符,则返回0

举例:

select find_in_set('ab','ef,ab,de') from lxw_dual;

2

select find_in_set('at','ef,ab,de') from lxw_dual;

0

  • 在一个字符串中搜索指定的字符,返回发现指定的字符的位置: INSTR(C1,C2,I,J)

返回substr在str中第一次出现的位置。若任何参数为null返回null,若substr不在str中返回0。Str中第一个字符的位置为1

C1 被搜索的字符串

C2 希望搜索的字符串

I 搜索的开始位置,默认为1

J 出现的位置,默认为1

SQL> select instr("abcde",'b');
结果是2,即在字符串“abcde”里面,字符串“b”出现在第2个位置。如果没有找到,则返回0;不可能返回负数

模糊搜索:
你先建立个表,包含city_id 和address  然后join  再instr(address_text,address)
select
instr(b.address_text,a.hei_adr),
a.*,
b.*
from
(select
*
from
analyst.hei_adr_sheet_003) a
left join
(select
 *
from dw.dw_prd_restaurant_wide
where dt=get_date(-1)) b
on a.hei_city=b.city_name
having instr(b.address_text,a.hei_adr) >0
 
  • 行转多列LATERAL VIEW explode

lateral view用于和split、explode等UDTF一起使用的,能将一行数据拆分成多行数据,

在此基础上可以对拆分的数据进行聚合,lateral view首先为原始表的每行调用UDTF,UDTF会把一行拆分成一行或者多行,lateral view在把结果组合,产生一个支持别名表的虚拟表。

1. 单个LATERAL VIEW:

源表(table1)数据{A:string B:array<BIGINT> C:string}
 A                  B                      C
190     [1030,1031,1032,1033,1190]      select id
191     [1030,1031,1032,1033,1190]      select id

select A,B,C from table_1 LATERAL VIEW explode(B) table1
结果如下:

190    1030  select id
190    1031  select id
190    1032  select id
190    1033  select id
190    1190  select id
191    1030  select id
191    1031  select id
191    1032  select id
191    1033  select id
191    1190  select id

2. 多个LATERAL VIEW

Array<int> col1  Array<string> col2
[1, 2]           [a", "b", "c"]
[3, 4]           [d", "e", "f"]

SELECT myCol1, myCol2 FROM baseTable
LATERAL VIEW explode(col1) myTable1 AS myCol1
LATERAL VIEW explode(col2) myTable2 AS myCol2;

结果如下:
int myCol1 string myCol2
1 "a"
1 "b"
1 "c"
2 "a"
2 "b"
2 "c"
3 "d"
3 "e"
3 "f"
4 "d"
4 "e"
4 "f"

 

 复杂方式:

select * from tb_split;

20141018  aa|bb 7|9|0|3

20141019  cc|dd  6|1|8|5

使用方式:select datenu,des,type from tb_split 

lateral view explode(split(des,"//|")) tb1 as des

lateral view explode(split(type,"//|")) tb2 as type

执行过程是先执行from到 as cloumn的列过程,在执行select 和where后边的语句;

  • str_to_map(text[, delimiter1, delimiter2])
使用两个分隔符将文本拆分为键值对。 Delimiter1将文本分成K-V对,Delimiter2分割每个K-V对。对于delimiter1默认分隔符是',',对于delimiter2默认分隔符是'='


案例1:
hive> 
    > select str_to_map('aaa:11&bbb:22', '&', ':')
    > from tmp.tmp_jzl_20140725_test11;

{"bbb":"22","aaa":"11"}

案例2:
hive> select str_to_map('aaa:11&bbb:22', '&', ':')['aaa']

11

案例3:
可代替 case when

a.storage_type,                        ----存储方式1常温2冷藏3冷冻
a.str_to_map('1=常温&2=冷藏&3=冷冻','&','=')[a.storage_type]     as storage_name     ----线上系统有变更需做相应的更改

    原文作者:张志豪
    原文地址: https://zhuanlan.zhihu.com/p/43903800
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞