Presto和Spark语法差异

一、同类实现差异

1、Presto整数相除沿用了Java整数相除的特性,而Spark除法会得到小数。

示例:

select 5/2;

Presto返回2,Spark返回2.5。

2、Presto的substr()函数的子字符串索引从1开始,而spark从0开始。

示例:

select substr('123', 0, 2);

Spark会返回结果12,Presto会返回空,除非写select substr('123', 1, 2);

3、Presto的字符串类型是varchar,而Spark是string。

示例:

select cast (1 as string);

Spark会返回1,而Presto会报错。

4、对于双引号,Spark会当成普通字符串,而Presto会当成列名,要当成普通字符串需要用单引号表示。

示例:

select "col" -- Spark会当作字符串,Presto会当成列名
select 'col' -- 这样Presto才会当成字符串

5、正则表达式转义方式不同。

示例:

select RLIKE( '1 2', '\\S');      -- Spark写法
select regexp_like( '1 2', '\S')  -- Presto写法

6、如果SQL查询的过滤条件中包含tab等制表符特殊字符,Presto和Spark基于的判断方式不一致,因为Presto中小于十六进制的空格符都会过滤掉,而Spark只会判断是否是0x20,所以tab(0x09)等过滤不掉,这样会导致结果可能不一致。

示例:

select * from bili_main.dws_prty_arch_tag_es_a_d where log_date='20220221' and length(trim(tag)) =0;

该查询中tag列中包含特殊空格制表符,如下图所示:

Presto和Spark语法差异_第1张图片

 因此此时Presto能返回一条结果,而Spark不返回结果,如下图所示:

Presto和Spark语法差异_第2张图片

7、Presto在正则表达式中使用单反斜杠'\',而hive和spark使用双反斜杠'\\'。

示例:

select
regexp_extract(
  'http://127.0.0.1:10052/upgcxcode/32/44/546274432/546274432-1-31101.m4s?xyip=127.0.0.1&xyport=10052&xy_usource=aa.com&xy_mark=bb.com&e=cc_dd_&uipk=5&nbs=1&deadline=1647178906&gen=playurlv2&os=rsc&oi=613971396&trid=ee&platform=android&upsig=ff&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,platform&pcdnid=1000007227&mid=240681701&bvc=vod&nettype=1&orderid=0,2&bw=175588&logo=8',

  '(\\-[0-9]+\\-)([0-9]+\\.(flv|m4s|mp4))',2
  )

​

在Presto中,末尾处的正则表达式应该用单反斜杠才有结果,如下所示:

select
regexp_extract(
  'http://127.0.0.1:10052/upgcxcode/32/44/546274432/546274432-1-31101.m4s?xyip=127.0.0.1&xyport=10052&xy_usource=aa.com&xy_mark=bb.com&e=cc_dd_&uipk=5&nbs=1&deadline=1647178906&gen=playurlv2&os=rsc&oi=613971396&trid=ff&platform=android&upsig=gg&uparams=e,uipk,nbs,deadline,gen,os,oi,trid,platform&pcdnid=1000007227&mid=240681701&bvc=vod&nettype=1&orderid=0,2&bw=175588&logo=8',

  '(\-[0-9]+\-)([0-9]+\.(flv|m4s|mp4))',2
  )

​

8、presto获取map格式数据的值时,如果有些行的map数据的指定key值缺失,就会报错"Key not present in map",而spark和hive返回null。

示例:

select m[3] from (select map(ARRAY[1,3], ARRAY[2,4]) as m

解决方法:使用element_at(map(K, V), key)获取值,不要用map[key]写法。参考: Presto与众不同的那些坑_while(True):的博客-CSDN博客_presto unnest写在前面:presto官方文档https://prestodb.io/docs/0.215/functions.html一、时间差presto 时间差:select date_diff('day',cast('2018-09-05' as date),cast('2018-09-07' as date));hive 时间差:select datediff('2018-0...https://blog.csdn.net/qq_37833410/article/details/103270386

9、timestamp类型列写入ORC文件时,presto默认会在stripe footer处同时写入UTC时区标志,而Spark2.3+默认采用native orc writer,会在stripe footer处写入jvm本地时区标志(如东八区),因此使用trino读取spark写入的文件时,trino会识别到stripe footer中的时区标志,进行本地时间偏移转换并展示,可能会和spark读取的utc timestamp列结果不同。

解决方法:(1)在spark-defaults.conf中设置如下参数,并重写orc文件:

spark.sql.hive.convertMetastoreOrc false
spark.sql.orc.impl hive

(2)使用presto sql语句中的at time zone语句查询,此时会将本地时间戳还原成utc时间戳展示:

select a at time zone 'UTC' from test_timestamp;

二、仅Presto支持

1、Presto支持Array index写法,而Spark不支持。

示例:

select array[1,2,3][1]

Presto会返回第一个元素即1,而Spark会报错。

三、仅Spark支持

1、&操作符。

示例:

select 1 & 3;

Spark会返回1,而Presto会报错。

2、rlike关键字。

示例:

select 1 rlike 3;

Spark会返回false,而Presto会报错。

3、int()函数。

示例:

select int(2.1)

Spark会返回2,而Presto会报错未注册。

4、concat_ws()函数,Presto会报错未注册。

5、lateral view关键字。

示例:

SELECT student, score FROM tests LATERAL VIEW explode(scores) t AS score

但Presto可通过如下语法实现类似逻辑:

SELECT student, score
FROM tests
CROSS JOIN UNNEST(scores) AS t (score);

6、cluster by与distribute by关键字。

示例:

SELECT student, score FROM tests distribute by student;
SELECT student, score FROM tests cluster by student;

7、sort by关键字,但Presto支持order by关键字。

你可能感兴趣的:(Presto,spark,presto,trino,语法,差异)