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

这篇具有很好参考价值的文章主要介绍了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');

hive 支持 execute immediate吗,hive,oracle,hive

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

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

hive 支持 execute immediate吗,hive,oracle,hive

 hive的

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

hive 支持 execute immediate吗,hive,oracle,hive

 如果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是日期类型 就可以想要什么格式要什么格式

hive 支持 execute immediate吗,hive,oracle,hive

 如果我们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') 

hive 支持 execute immediate吗,hive,oracle,hive

 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

hive 支持 execute immediate吗,hive,oracle,hive

字段格式是: 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是正则

hive 支持 execute immediate吗,hive,oracle,hive

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 

hive 支持 execute immediate吗,hive,oracle,hive

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

hive 支持 execute immediate吗,hive,oracle,hive

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

说下思路

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 ;

hive 支持 execute immediate吗,hive,oracle,hive

结果也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

hive 支持 execute immediate吗,hive,oracle,hive

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

hive 支持 execute immediate吗,hive,oracle,hive

 等价于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  <tableb.period , v_start_period+0  ,null) month01,
if(v_start_period+1  <tableb.period , v_start_period+1  ,null) month02,
if(v_start_period+2  <tableb.period , v_start_period+2  ,null) month03,
if(v_start_period+3  <tableb.period , v_start_period+3  ,null) month04,
if(v_start_period+4  <tableb.period , v_start_period+4  ,null) month05,
if(v_start_period+5  <tableb.period , v_start_period+5  ,null) month06,
if(v_start_period+6  <tableb.period , v_start_period+6  ,null) month07,
if(v_start_period+7  <tableb.period , v_start_period+7  ,null) month08,
if(v_start_period+8  <tableb.period , v_start_period+8  ,null) month09,
if(v_start_period+9  <tableb.period , v_start_period+9  ,null) month10,
if(v_start_period+10 <tableb.period , v_start_period+10 ,null) month11,
if(v_start_period+11 <tableb.period , v_start_period+11 ,null) month12

-- 这里就是比较每个月是否<tableb.period,如果小于 就直接填充月份,不满足就是null,这里的null后面有用

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 支持 execute immediate吗,hive,oracle,hive

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')

hive 支持 execute immediate吗,hive,oracle,hive

 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

hive 支持 execute immediate吗,hive,oracle,hive

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 )

hive 支持 execute immediate吗,hive,oracle,hive

怎么解决上述问题呢?  有时候我也不知道是字符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

hive 支持 execute immediate吗,hive,oracle,hive

 很遗憾这两个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

hive 支持 execute immediate吗,hive,oracle,hive

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

注意是没有计算时分秒功能的。文章来源地址https://www.toymoban.com/news/detail-630107.html

到了这里,关于oracle和hive之间关于sql的语法差异及转换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Shell语法揭秘:深入探讨常见Linux Shell之间的语法转换

    博主简介 💡一个热爱分享高性能服务器后台开发知识的博主,目标是通过理论与代码实践的结合,让世界上看似难以掌握的技术变得易于理解与掌握。技能涵盖了多个领域,包括C/C++、Linux、Nginx、MySQL、Redis、fastdfs、kafka、Docker、TCP/IP、协程、DPDK等。 👉 🎖️ CSDN实力新星、

    2024年02月11日
    浏览(39)
  • Hive-SQL语法大全

    如上语法,在语法描述中出现: [] ,表示可选,如上 [LOCATION] 表示可写、可不写 | ,表示或,如上 ASC | DESC ,表示二选一 …,表示序列,即未完结,如上 SELECT expr, ... 表示在SELECT后可以跟多个 expr(查询表达式) ,以逗号隔开 () ,表示必填,如上(A | B | C)表示此处必填,填

    2024年01月25日
    浏览(43)
  • Hive SQL 优化大全(参数配置、语法优化)

    服务器环境说明 机器名称 内网IP 内存 CPU 承载服务 master 192.168.10.10 8 4 NodeManager、DataNode、NameNode、JobHistoryServer、Hive、HiveServer2、MySQL slave1 192.168.10.11 8 4 NodeManager、DataNode、ResourceManager slave2 192.168.10.12 8 4 NodeManager、DataNode、SecondaryNameNode 操作系统均为: CentOS 7.5 组件版本 jdk 1

    2024年02月10日
    浏览(47)
  • Oracle PL/SQL基础语法学习13:比较运算符

    Oracle PL/SQL基础语法学习12:短路求值 Oracle PL/SQL基础语法学习13:比较运算符 Oracle PL/SQL基础语法学习14:BOOLEAN表达式 【免责声明】文章仅供学习交流,观点代表个人,与任何公司无关。 编辑|SQL和数据库技术(ID:SQLplusDB) 比较运算符是 PL/SQL 语言中的基本元素之一,它们被用于

    2024年02月05日
    浏览(51)
  • Oracle开发和应用——PL/SQL语法2(游标及集合)

    6.4.6.  游标 这里的游标 (cursor) ,是指数据库开发中的游标,而且,这里所指的是显式定义的游标。因为,除了显式定义的游标,我们每条SQL语句也会隐式的定义、打开和关闭一个游标,其实质是一个带有指针的结果集。当我们按照顺序取出结果时,这个指针会按照从前到

    2024年02月22日
    浏览(44)
  • SQL SERVER日期与字符串之间的转换

    本文导读:在SQL Server数据库中,SQL Server日期时间格式转换字符串可以改变SQL Server日期和时间的格式,是每个SQL数据库用户都应该掌握的。下面主要就介绍一下SQL Server日期时间转字符串的相关知识 一、日期转换为字符串、日期格式 1、使用函数CONVERT: 2、参数 expression :是任

    2024年02月10日
    浏览(51)
  • 【SQL应知应会】行列转换(三)• Oracle版

    欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享,与更多的人进行学习交流 本文收录于SQL应知应会专栏, 本专栏 主要用于记录对于数据库的一些学习,有基础也有进阶,有MySQL也有Oracle

    2024年02月12日
    浏览(46)
  • SQL Server日期时间与字符串之间的转换

    1、使用函数CONVERT: 2、参数说明 expression :任何有效的SQL表达式。 data_type :目标数据类型。 这包括 xml、bigint 和sql_variant 。 不能使用别名数据类型。 length :指定目标数据类型长度的可选整数,适用于允许用户指定长度的数据类型。例如:nchar、nvarchar、char、varchar、binary

    2024年02月06日
    浏览(55)
  • 关于hive sql进行调优的理解

            这是一个面试经常面的问题,很不幸,在没有准备的时候,我面到了这个题目,反思了下,将这部分的内容进行总结,给大家一点分享。         hive其实是基于hadoop的数据库管理工具,底层是基于MapReduce实现的,用户写的hivesql最终转换成MapReduce的任务运行在

    2024年02月11日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包