oracle和hive之间关于sql的语法差异及转换

1. oracle的(+) 改为hive左右连接 

oracle (+)学习_cclovezbf的博客-CSDN博客最近工作需要将oracle的存储过程转化为hive的sql脚本。遇到很多不一样的地方,例如oracle连接中有(+)号的用法。借鉴这篇文章,但是这个排版比较烂。。。先建表和插入数据首先说明(+)代表什么?代表这一侧的数据可以为空!a.id=b.id(+) 代表b表和a表关联的时候以a表作为主表。https://blog.csdn.net/cclovezbf/article/details/128305437

2.select中含有子查询

例如select a.id, (select b.id from b where b.name=a.id) from a 

hive 是不支持select 里面子查询的。  修改如下

select a.id ,b.id from a left join b on a.id=b.name

3.oracle的decode函数

decode('key',if1,then1 ,if2,then2...thenN)

一般来说可以改为case key when if1 then then1  when if2 then then2 else thenN

但是如果decode比较简单 可以直接改为 if('key'=if1,then1,then2)

复杂的改为case when   。特别注意hive有个decode函数是编码函数

4.oracle的时间转化

例如某字符串yyyyMM获取上个月时间

oracle

select to_char(add_months(to_date('202202','yyyymm'),-1),'yyyymm') from dual

hive 

select date_format(add_months(to_date(from_unixtime(unix_timestamp('202212','yyyyMM'))) ,-1),'yyyMM');

其实可以简化

select add_months(from_unixtime(unix_timestamp('202212','yyyyMM')),-1,'yyyMM');

oracle和hive之间关于sql的语法差异及转换_第1张图片

5.oracle的 to_char 格式化时间格式

select to_char(sysdate ,'YYYY-MM-DD') from dual 

oracle和hive之间关于sql的语法差异及转换_第2张图片

 hive的

select to_date(current_timestamp); --这里返回值是date!!!!

oracle和hive之间关于sql的语法差异及转换_第3张图片

 如果hive要转化为其他格式 可以用date_format(current_date,'yyyy-MM-dd HH:mm:ss')

这里要注意oracle对格式要求比较严格,hive则不需要特别严格。

我们这边为了图方便把hive的日期格式都拿string去存,所以会有些些出入

例如oracle

SELECT 'yyyyMM', to_char (SYSDATE,'yyyyMM') FROM dual UNION ALL 
SELECT 'yyyy-MM', to_char (SYSDATE,'yyyy-MM') FROM dual UNION ALL 
SELECT 'yyyy-MM-dd', to_char (SYSDATE,'yyyy-MM-dd') FROM dual UNION ALL 
SELECT 'yyyy/MM/dd', to_char (SYSDATE,'yyyy/MM/dd') FROM dual 

oracle的to_char 函数非常方便只要你的入参1是日期类型 就可以想要什么格式要什么格式

oracle和hive之间关于sql的语法差异及转换_第4张图片

 如果我们hive存的是日期格式也还好

hive的date类型格式化

SELECT 'yyyyMM', date_format (current_date(),'yyyyMM')  UNION ALL 
SELECT 'yyyy-MM', date_format (current_date,'yyyy-MM') UNION ALL 
SELECT 'yyyy-MM-dd', date_format (current_date,'yyyy-MM-dd') UNION ALL 
SELECT 'yyyy/MM/dd', date_format (current_date,'yyyy/MM/dd') 

oracle和hive之间关于sql的语法差异及转换_第5张图片

 hive的string 类型格式。 如果你存标准日期格式例如 2022-12-13 14:15:16 可以直接按照上面写。

但是如果你存的是20221213 2022/12/13这种格式。(当然你可以substring+ concat("-")拼)。

说点其他的。

可以通过如下方法格式,我们只需要修改format对应hive表里用string存储的日期格式即可

select from_unixtime(UNIX_TIMESTAMP('20200102','yyyyMMdd')--2020-01-02 00:00:00
select to_date(from_unixtime(UNIX_TIMESTAMP('20200102','yyyyMMdd'))) -- 2020-01-02

说个简单且经常遇到的的转化 

oracle ->TO_CHAR(TO_DATE(REPLACE(ADJ.VAR1, '-',''), 'YYYYMMDD'), 'yyyy')

hive -> from_unixtime(UNIX_TIMESTAMP(REPLACE(ADJ.VAR1, '-',''), 'YYYYMMDD'), 'yyyy')

6.oracle的trunc函数

https://blog.csdn.net/cclovezbf/article/details/128326389https://blog.csdn.net/cclovezbf/article/details/128326389

7.oracle instr函数 

参考文章

Oracle中的instr()函数 详解及应用_Java&Develop的博客-CSDN博客_oracle中instr

SELECT instr('1234567890123456789','3') FROM dual  -- 3
SELECT instr('1234567890123456789','3',1) FROM dual  -- 3 ,从第1位开始查找第一个3
SELECT instr('1234567890123456789','3',1,2) FROM dual --13 从第1位开始查找第二个3
SELECT instr('1234567890123456789','3',4) FROM dual   -- 13  从第4位开始查找第一个3
SELECT instr('1234567890123456789','3',4,1) FROM dual  --13 从第4位开始查找第一个3
SELECT instr('1234567890123456789','3',4,2) FROM dual  --0  从第4位开始查找第二个3

select instr('被查找的字符串','我们需要查找的字符',从第几位开始 首位是0,查找第几个出现的)

注意这里返回的下标是从1开始的。

接着我们来看下hive的函数 有几个类似的 instr 

instr(str, substr) - Returns the index of the first occurance of substr in str

SELECT instr('1234567890123456789','3') -- 3 没问题 但是这个功能比较简单,远没有oracle的强大,不过也凑合用了。

hive-locate函数

 select locate('3','12345123',4) --8
 select locate('3','12345123',1) --3

-- 这个locate函数也是找到字符串的下标 locate('要找的字符','被找的字符串',' 从下标多少开始找')。

说实话 感觉这个函数也没有oracle instr的函数好用,因为 instr(str,substr, count) 可以找第几次出现 对于 xx.xx.xx 和x.x.x 这种格式的数据特别好用

说个遇到的案例 oracle中  需要截取某个字段

SELECT 
SEGMENT_NAME_MERGE, 
SUBSTR(T.SEGMENT_NAME_MERGE,
       INSTR(T.SEGMENT_NAME_MERGE, '.', 1, 2) + 1,
       (INSTR(T.SEGMENT_NAME_MERGE, '.', 1, 3) - INSTR(T.SEGMENT_NAME_MERGE, '.', 1, 2)) - 1
       ) 
FROM ODSERPDATA.ODS_CE_GL_ACCOUNT_Q T

oracle和hive之间关于sql的语法差异及转换_第6张图片

字段格式是: xx1.xxxxx2.xx3.xxx4.xx5.xx6   我们需要xx3格式的数据

缺省.受限制现金-人民币-风险准备金专户.工行高新支行321413RMB(财付通专用).缺省.缺省.缺省.缺省.缺省   ->  工行高新支行321413RMB(财付通专用)

之前的人采用了substring('字符串',第二个.字符的下标+1, (第三个. - 第二个.的长度 + 1))。

现在我们要在hive中也截取成这样。 我们能一样采用instr +substr吗?

不能!!! 因为hive的instr只能定位到第一个.   那我们怎么办?

这里我们可以使用substring_index 或regexp_extract

select  replace(substring_index(a,'.',3),substring_index(a,'.',2)||'.',''),
substr(a,length(substring_index(a,'.',2))+2,length(substring_index(a,'.',3))-length(substring_index(a,'.',2))-1),
       regexp_extract(a,'.*?\\..*?\\.(.*?)\\.+',1)
from (select '缺省.受限制现金-人民币-风险准备金专户.工行高新支行321413RMB(财付通专用).缺省.缺省.缺省.缺省.缺省' a )t
上面是三种办法。 1.是替换 2.是截取 3是正则

oracle和hive之间关于sql的语法差异及转换_第7张图片

8.临时表名

oracle 这样是可以的

SELECT * FROM (SELECT 1,2 FROM dual )

hive注意必须临时表名

select * from (select 1, 2 )t  --正确

select * from (select 1, 2 )  --错误 

9.with插入用法。

oracle 

INSERT INTO  TEST.CC_STUDENT_02
WITH tmp AS (SELECT * FROM TEST.CC_STUDENT_02 cs )
SELECT * FROM tmp 

hive 顺序有点不同

WITH tmp AS (SELECT * FROM TEST.CC_STUDENT_02 cs )

INSERT INTO  TEST.CC_STUDENT_02
SELECT * FROM tmp 

10.计算语法 或者||用法不同

oracle

SELECT substr('202212', 1, 4) - 1 || 'aa' FROM dual   -- 2021aa

hive 

SELECT substr('202212', 1, 4) - 1 || 'aa' -- 2021.0aa

解决办法

SELECT cast(substr('202212', 1, 4) - 1 as int)|| 'aa' -- 2021aa

SELECT cast(substr('202212', 1, 4) as int) - 1|| 'aa' -- 2021aa

因为int-int=int 。 string-int 和int-string=double

这是因为hive 在'2022'-1的时候计算结果是double类型  double+string 保留了一位小数

oracle

SELECT 1||NULL||2 FROM dual  -- 12

hive

SELECT 1||NULL||2   --null

解决办法

select 1||nvl(null,'')||2 

——————————————————————————————————————————

最近遇到了一个特别搞人的oracle时间转化。就是oracle有个string字段里面的日期格式非常不标准有 - / 然后01省略0的,但是通过to_date函数都可以转化

不得不说oracle的to_date函数非常强大可以转化不标准的时间字符串为date类型

SELECT to_date('2017-3-31', 'yyyy/mm/dd') FROM dual UNION ALL 
SELECT to_date('2018/11/6', 'yyyy/mm/dd') FROM dual UNION ALL 
SELECT to_date('2017/6/20', 'yyyy/mm/dd') FROM dual UNION ALL 
SELECT to_date('2017-06-20', 'yyyy/mm/dd') FROM dual UNION ALL 
SELECT to_date('20170620', 'yyyy/mm/dd') FROM dual 

oracle和hive之间关于sql的语法差异及转换_第8张图片

 hive呢? hive怎么搞? var9就是原列,trade_date就是转化后的。案例中的20170620是不存在的(我自己造的)。。

oracle和hive之间关于sql的语法差异及转换_第9张图片

此时我已经想到了一个复杂的办法。。。

说下思路

1.自己定义一个udf函数,用java的方式去判断然后补充0 成为标准的时间字符串

2.我想到了oracle的instr函数可以获取的第一个和第二个 / 或 - 的位置 然后根据位置来补充0

3.第2个没问题 但是注意看我的第7点,hive的instr函数阉割了这个功能。

  所以需要找其他函数 有两种

一种是通过 index获取 月份和天的具体下表 ,这个可以用subtring_index。

一种是通过正则直接提取。 我直接用这个regexp_extract了

select 
y||'-'||if(length(m)=1,0||m,m)||'-'||if(length(d)=1,0||d,d)
from (
select 
replace(a,'/','-') a ,

regexp_extract(replace(a,'/','-'),'(\\d+)-(\\d+)-(\\d+)',1) y,

regexp_extract(replace(a,'/','-'),'(\\d+)-(\\d+)-(\\d+)',2) m,

regexp_extract(replace(a,'/','-'),'(\\d+)-(\\d+)-(\\d+)',3) d 
from (
select '2020/3/23'as a union all 
select '2019-12-1'as a union all 
select '2019-12-6'as a union all 
select '2018/7/6'as a
)t 
)t1 ;

oracle和hive之间关于sql的语法差异及转换_第10张图片

结果也ok,但是总感觉很lowb 有没有和oracle一样的to_date可以解决这个问题的呢? 我是暂时没看到,有没有小伙伴能够解决,可以留言,感激不尽。

---------------------------2023-02-24更新------------------------

最近发现了一个比较简单的算法。。。。

select to_date(replace(t.a ,'/','-'))
from (
         select '2020/3/23'as a union all
         select '2019-12-1'as a union all
         select '2019-12-6'as a union all
         select '2018/7/6'as a
     )t

oracle和hive之间关于sql的语法差异及转换_第11张图片

10 to_char(date,iw)

oracle是真吉儿复杂。 简简单单的一个算第几周的函数搞这么复杂

oracle的iw算法,关于Oracle to_char()函数中的IW,WW 周别显示 ._liu威的博客-CSDN博客

hive是不行了。但是有个weekofyear()凑合用吧

oracle ww 初始不完整的一周算第一周  iw 是完整的第一周才算第一周

hive的还没尝试。。

11、WM_CONCAT

这个函数其实和mysql的group_concat 差不多 ,都是列转行。

SELECT t.id ,to_char(WM_CONCAT(name )),WM_CONCAT(name )
FROM (
SELECT 1 AS id ,1 as name  FROM dual UNION ALL 
SELECT 1 AS id ,2 as name  FROM dual UNION ALL 
SELECT 1 AS id ,1 as name  FROM dual UNION ALL 
SELECT 2 AS id ,4 as name  FROM dual UNION ALL 
SELECT 2 AS id ,5 as name  FROM dual 
)t 
GROUP BY t.id

oracle和hive之间关于sql的语法差异及转换_第12张图片

 等价于hive的

concat_ws(',',collect_list(column))

因为可以看到oracle没有去重,所以collect_list即可,不需要用collect_set

12 FOR IN LOOP

其实不想写这个。。之前遇到了几个简单的loop,我都通过shell来实现,后来发现之前的pkg写的是越来越过分。。。没办法只能加强的学习一波。

【Oracle】for in loop_Hi竹子的博客-CSDN博客

FOR 结果集 IN (
        SELECT [匹配字段],[更新字段] FROM A表
) loop
        UPDATE B表
            SET B表.[需要更新字段]= 结果集.[更新字段];
        WHERE
             B表.[匹配字段]= 结果集.[匹配字段];
END loop ;

---------------------------------------------------
  SQL执行含义:
    先执行IN里的SQL,得到结果集;
    循环结果集,结果集可用于 loop里的SQL。

单看这么一段可能不太好理解。直接来实战 ---

不举例了。 其实简单的循环可以通过shell来实现。在shell里写while循环

有点实战不动了,我这边的例子里是个 for in loop , while ()   end loop 里面搞了一个递归,日了狗了,只能想着用spark代码去跑递归了。

这里我遇到了一个比较简单的循环,给大家展示下如何直接在hive里处理不经过shell和其他方法。

oracle pck

-- V_START_PERIOD := V_YEAR_ID || '01';
-- V_END_PERIOD   := V_YEAR_ID || '12';

--Part3、增长率计算:自动计算按增长率预估的数据
WHILE V_START_PERIOD <= V_END_PERIOD LOOP

        insert into tableA

        select v_start_period, column1 ,column2

        from tableB

        where v_start_period< tableB.period_id

V_START_PERIOD := V_START_PERIOD + 1;

END LOOP;

整个核心就是 从202301开始到202312 一次次比较tableB.period_id.符合就插入数据。

其实本质插入的数据基本差不多,只是有个v_start_period随着循环变化

---更新下 之前说错了 随着日期的变化 数量也在变化    

where 202301< tableB.period_id 和 where 202302< tableB.period_id 的数据量肯定不一样

我遇到的有的where是固定的where 202301< tableB.period_id

也有这种不固定的 where v_start_period< tableB.period_id

怎么用hive写呢?

固定的where 条件 where 202301< tableB.period_id,

核心思想 这个本质还是一份数据插入了多次。 一行变多行 就得拿出lateral view了。

with tmp as (

select *,

if(v_start_period+0   if(v_start_period+1   if(v_start_period+2   if(v_start_period+3   if(v_start_period+4   if(v_start_period+5   if(v_start_period+6   if(v_start_period+7   if(v_start_period+8   if(v_start_period+9   if(v_start_period+10 if(v_start_period+11

-- 这里就是比较每个月是否

from tableb

)

select

*,

tmp.period_id --这个id就是满足的条件的所有id

from tmp later view explode(concat_ws(',',month01,month02。。。。month12)) tmp as period_id

为什么上面用null不用’‘呢 因为concat_ws的时候如果是null直接忽略,如果是空就会是month01,,,,,,,,,,,,

当然这种改法有一定的局限性。比如不太适合循环太多的

14 日期 格式化

oracle   大小写不敏感 YYYY-MM-DD HH24:MI:SS和yyyy-mm-dd hh24:mi:ss 都行

SELECT to_date('2023-01-02 15:55:03', 'yyyy-mm-dd hh24:mi:ss'),TO_DATE('2023-01-02 15:55:03', 'YYYY-MM-DD HH24:MI:SS')FROM dual

hive 标准格式 yyyy-MM-dd HH:mm:ss.SSS (当然yyyy和YYYYY看着一样) hh小写是12进制

 select date_format('2023-03-17 16:23:37.330000000','yyyy-MM-dd HH:mm:ss.SSS')
     ,date_format('2023-03-17 16:23:37.330000000','YYYY-MM-DD hh:mm:SS.SSS')

 15 类型兼容问题

因为hive有个类型自动转化问题,比如 id(int)='1' 也是可以查的,平常的时候确实很方便,但是有的地方会出大问题。

简单来说

hive '1'+1是有可能出问题的

oracle  '1'+1 没有问题

select '999'>'1000' , 999 > 1000  -- true  false

--前者为true 后者为false。 为啥呢? 因为这种比较大小对于字符串来说 是比较顺序,1000的顺序是小于999的顺序的,字符串的顺序是123456789

with t as (
    select '1' a union all
    select '11'a union all
    select '2' a union all
    select '3' a
)
select t.a from t  order by a

oracle和hive之间关于sql的语法差异及转换_第13张图片

with t as (
    select '1' a union all
    select '11'a union all
    select '2' a union all
    select '3' a
)
select t.a from t  order by cast(a as int )

oracle和hive之间关于sql的语法差异及转换_第14张图片

怎么解决上述问题呢?  有时候我也不知道是字符string 还是int

可以将上面的改为

select '999'-'1000'>0,999-1000>0 即可。不过这个也会有点点小小的问题。

16.Oracle中pivot/和unpivot函数 

如下。

oracle 学习之 unpivot/pivot函数及hive实现该功能_cclovezbf的博客-CSDN博客

17.RPAD LPAD (左右填充函数)

lpad函数从左边对字符串使用指定的字符进行填充基本语法:lpad( string, padded_length, [ pad_string ]

oracle

SELECT RPAD ('1234',10),LENGTH(RPAD ('1234',10)) FROM dual 

-- 1234      10  --注意 1234后面又6个空格

SELECT RPAD ('1234',10,'a'),LENGTH(RPAD ('1234',10,'a')) FROM dual 

1234aaaaaa 10

padded_length 就是你想要的位数有多长

pad_string 是默认空格,填充字符

hive

SELECT RPAD ('1234',10),LENGTH(RPAD ('1234',10))  --报错 必须有三个入参

 正确写法

SELECT RPAD ('1234',10,' '),LENGTH(RPAD ('1234',10,' '))  

1234      ,10 

 所以oracle 经常有 RPAD ('1234',10) 在hive里就需要多写一个空格 RPAD ('1234',10,' ')

继续更新 真是搞不动了 奉劝各位以后要是做oracle pck转hivesql的活 赶紧放弃吧,要是pck是你写的还行。不是你写的 真的是难搞。

18 oracle函数REGEXP_SUBSTR和 REGEXP_COUNT

oracle和hive之间关于sql的语法差异及转换_第15张图片

 很遗憾这两个b函数hive都没有。所以要想办法用啥替换呢?先学习下这两个函数,先佩服下oracle真是啥函数都有 一大堆。

Oracle分割字段的值并且返回多行数据(使用regexp_substr和regexp_count函数)_good_good_xiu的博客-CSDN博客

REGEXP_SUBSTR()
function REGEXP_SUBSTR(String, pattern, position, occurrence, modifier)

string:需要进行正则处理的字符串
pattern:进行匹配的正则表达式
position:起始位置,从字符串的第几个字符开始正则表达式匹配(默认为1) 注意:字符串最初的位置是1而不是0
occurrence:获取第几个分割出来的组(分割后最初的字符串会按分割的顺序排列成组)
modifier:模式(‘i’不区分大小写进行检索;‘c’区分大小写进行检索。默认为’c’)针对的是正则表达式里字符大小写的匹配
使用REGEXP_SUBSTR()进行逗号的匹配、字符串的分割和获取。

这个b玩意看起来和hive的split有点像 

oracle

SELECT REGEXP_SUBSTR('1234,4567', '[^,]+', 1, 1) FROM dual; -- 1234

后面两个参数可以省略 默认都是1

SELECT REGEXP_SUBSTR('账号2543071133-腾讯云','\d+')  FROM dual  --2543071133

hive

select split('1234,4567',',')[0]  -- 1234 

其实还有一个函数就是regexp_extract

SELECT regexp_extract('账号2543071133-腾讯云','(\\d+)',1) 

我有篇文章也提到这个函数 

hive之正则函数研究学习regex/regex_replace/regex_extract_hive regex_cclovezbf的博客-CSDN博客首先学习这个之前要先知道一些正则的基本知识。随便百度一下将下一个字符标记为一个特殊字符、或一个原义字符、或一个 向后引用、或一个八进制转义符。例如,'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置。匹配输入字符串的结束位置。https://blog.csdn.net/cclovezbf/article/details/129422382

regexp_count()
Oracle的11g引入此函数
REGEXP_COUNT ( source_char, pattern [, position [, match_param]])

source_char:需要进行正则处理的字符串
pattern :进行匹配的正则表达式
position:起始位置,从字符串的第几个字符开始正则表达式匹配(默认为1) 注意:字符串最初的位置是1而不是0
match_param:‘i’ 用于不区分大小写的匹配,‘c’ 用于区分大小写的匹配,‘n’ 允许句点(.)作为通配符去匹配换行符。如果省略该参数,则句点将不匹配换行符,‘m’ 将源串视为多行。即Oracle 将^和$分别看作源串中任意位置任何行的开始和结束,而不是仅仅看作整个源串的开始或结束。如果省略该参数,则Oracle将源串看作一行。‘x’ 忽略空格字符。默认情况下,空格字符与自身相匹配。
REGEXP_COUNT 返回pattern 在source_char 串中出现的次数。如果未找到匹配,则函数返回0。position 变量告诉Oracle 在源串的什么位置开始搜索。在开始位置之后每出现一次模式,都会使计数结果增加1。

这个玩意感觉也和split有关系

oracle 

SELECT REGEXP_COUNT('1234,5678',',')  FROM  dual  -- 1 这个是正则出现的次数  

SELECT REGEXP_COUNT('1234,5678',',') +1 FROM  dual   -- 2 这个是被切割的次数

这还好说 关键点来了。

这两个家伙加上connect by 组合使用  。

SELECT REGEXP_SUBSTR('1234,5678', '[^,]+', 1, ROWNUM) 
FROM dual 
CONNECT BY ROWNUM <= regexp_count('1234,5678', ',')+1;

--1234
--5678

注意这里是两列!!!!!!

这感觉突然一下子又简单起来了。 这个不就是一行变多行吗?

select  tmp.a from (
            select '1234,5678' as a
                )t lateral view  explode(split(a,',')) tmp as a  

但是你乍一看oracle的这个语法不就是完了完了。这该怎么改? 其实就是hive的later view 

19 EXECUTE IMMEDIATE

oracle 存储过程里有这么一句话看似平平无奇

EXECUTE IMMEDIATE 'SELECT ' || LV_FORMULA || ' FROM DUAL'
        INTO CALC_AMT;

但是这句话的实际含义是 把字符串LV_FORMULA='1+2+3+4' 转为计算结果

最后的 把结果1+2+3+4= 10赋值给calc_amt。。。也就是最后算出CALC_AMT=10

再简化下就是 某行  'a'   '1+2+3+4'  -> a  10 这么转化。

其实我已经有思路了。只是觉得不是特别好。(目前只适合加减法 不适合乘法) 仅供大家打开思路。 有好的想法可以留言让我学习。。。。

select a ,sum(s1)
from (
         select a,b,tmp.s,
                case 
                    when tmp.s regexp '(\\+)' then regexp_extract(s, '(\\d+)')  --这里如果是小数可以自行拓展
                    when tmp.s regexp '(\\-)' then negative(regexp_extract(s, '(\\d+)'))
                    else s end as s1
         from (
                  select 'cc' a, '1+2+3+4' b
                  union all
                  select 'zbf' a, '1+2+3-4' b
              ) t lateral view explode(split(b, '(?!\\d)')) tmp as s
         where length(s) > 0
     )t
group by a

oracle和hive之间关于sql的语法差异及转换_第16张图片

20.时间相减

oracle

SELECT SYSDATE -1 FROM dual  --获取昨天

SELECT to_date('2023-05-03','YYYY-MM-DD') -to_date('2023-05-02','YYYY-MM-DD') FROM dual  --1  两天时间差

SELECT SYSDATE -to_date('2023-05-02','YYYY-MM-DD') FROM dual

--9.64637731481481481481481481481481481481 时间差 计算了时分秒

hive 其实也可以时间相减

select `current_timestamp`(), `current_timestamp`() -to_date('2023-05-10')

-- 2023-05-11 15:33:00.779000000,1 15:33:00.779000000 但是不推荐 因为看起来既直观又不直观

计算时间差一般采用的是datediff函数

select datediff(`current_timestamp`(),to_date('2023-05-10'))  -- 1 

计算前几天后几天采用date_add date_sub

select  `current_date`(),date_add(`current_date`(),1),date_sub(`current_date`(),1)

2023-05-11,2023-05-12,2023-05-10

注意是没有计算时分秒功能的。

你可能感兴趣的:(hive,oracle,hive)