記錄oracle轉sparksql的問題

2021-08-17 20:36:22 字數 4325 閱讀 6219

1.listagg

行轉列函式

listagg(item_category_name 『,』) within

group(order by item_category_name)//oracle

經過多方查詢:

使用concat_ws(",」,collect_set(item_category_name)) //over (oder by item_category_name);//sparksql

2.regexp_substr(b.orgcode,』[^.]+』,1,2) 部門組

3010100.50320.1665.112

此函式為正則取部門編號即50320.

用sparksql替換為

regexp_extract(b.orgcode,』(\\d+)\\.(\\d+)\\.(\\d+).\\(\\d+)』,2)

取第二個匹配括號的值

3.select * from (select * from abc )

此處需要注意,必須要給from後巢狀的selelct子句外側加乙個表別名。

即select * from (select * from abc ) b,不然sparksql會報錯

4.with as等建立臨時表的操作一般採用中間registertemptable來進行,不用with as的語法。

5.對於oracle存過中sql過長的情況一般採用拆分的方式來進行,以免spark解析器無法解析sql報錯。

6.對於row_number()over (partion by ````)這種函式,容易報錯無法獲取記憶體資源,需要在**開頭加一段引數配置如

下:val sc=new sparkcontext(conf)

val sqlcontext=new hivecontext(sc)

sqlcontext.setconf(「spark.sql.tungsten.enabled」,「ture」)

7.sparksql 不支援oracle中update、delete關於多行資料的操作。一般來說用writeparquet進行落地,中間錶用registertemptable進行註冊臨時表來處理。這裡說一下對於落地的表需要載入到已經建好的表中,屬於overwrite的操作,所以一般對於增量層採用直接落地(有效期一般是一天左右),全量層資料一般用增量資料和以往全量進行union操作,實際上也是乙個update的操作。中間表一定需要droptemptable

8.對於監控日誌等需要做逐條插入的操作,sparksql可以使用

insert into table abc_cvt_injust select

變數1,變數2,變數3;

如以上語法可以滿足逐條插入的需求。

一般用於多個sql進行日誌監控,用一張表存放日誌資訊。

9.對於需要insert into 的表,去掉該語法,直接select ,然後將select的df 寫成parquet,然後再利用load 加載入hive表中,使用overwrite的方式,其中如果出現落地以後,select中出現多個相同字段,請給該列加乙個別名,別名參考具體插入的目標錶該列別名,否則寫入parquet會報錯出現相同列的問題,

10.對於oracle11g中出現unpivot的語法,可以使用

原本:

select user_account, signup_date, src_col_name, friend_email

from email_signup unpivot((friend_email) for src_col_name in(user_email,

friend1_email,

friend2_email,

friend3_email));

select user_account,signup_date,'user_email' as src_col_name,user_email as friend_email from email_signup

where user_email is not null

union

select user_account,signup_date,'friend1_email' as src_col_name,user_email as friend_email from email_signup

where friend1_email is not null

union

select user_account,signup_date,'friend2_email' as src_col_name,user_email as friend_email from email_signup

where friend2_email is not null

union

select user_account,signup_date,'friend3_email' as src_col_name,user_email as friend_email from email_signup

where friend3_email is not null;

具體參考:

11.遇到rollup和grouping一起混用的,在sparksql中無法使用多個rollup和字段並列group by。

group by a,b,rollup(c,d,e),rollup(f)
以上情況sparksql不支援必須改為單個rollup或cube。

with tmp1 as select 、、、、、

group by rollup(a,b,c,d,e,f)

union(去重)

select ''''''''

group by rollup(a,b,f,c,d,e)

tmp2 as select * from tmp1 f where

f.a is nou null and f.b is not null

使用兩個rollup把所有需要的情況合併去重以後再篩掉不需要的資料。用臨時表將結果篩掉不需要的資料。

decode(groupping(t.cassfolder),1,'900010',t.cassfolder)
單個grouping需要改為

case when t.cassfolder is null then '900010' else t.cassfolder end
12.使用scala xml解析,如果報錯出現for迴圈空指標問題,報錯地方為for迴圈頭部,其實為for迴圈內部某變數沒有賦值,報錯並不準確

13.pivot 在轉的過程中

select 

casefolderid, lastadjusttime, lastlawsuittime, lastpaybacktime

from a t1 pivot(max(operatetime) for task_def_key in('task_adjust'

lastadjusttime,

'task_lawsuit'

lastlawsuittime,

'task_payback'

lastpaybacktime)) ;

改為用如下轉換

select casefolderid,

max( case when task_def_key='task_adjust' then operatetime else null end) lastadjusttime,

max( case when task_def_key='task_lawsuit' then operatetime else null end) lastlawsuittime,

max( case when task_def_key='task_payback' then operatetime else null end) lastpaybacktime

from a

group by casefolderid

其實多複雜都可以用其變形

pivot (max(a)) for b in ('c' d)

變為max(case when b=c then a else null end ) d

group by others;

14.提示找不到***.parquet檔案

1.select 列有重名列

2.write parquet 前列印schema與目標表結構比對

3.目標表的路徑需要刪除重新建立

hadoop dfs -rm -r /hdfs/table

hadoop dfs -mkdir /hdfs/table

mysql轉oracle的採坑記錄

最近在將乙個開源的任務排程專案 xxl job 從mysql轉為oracle,之前採用的是mybatis mysql,現在改為mybatis oracle的結構,在轉換的過程中遇到了很多問題。mysql的分頁 select from xxl job info as t order by id des...

Oracle 行列轉置

兩種簡單的行列轉置 1 固定列數的行列轉換 如student subject grade student1 語文 80 student1 數學 70 student1 英語 60 student2 語文 90 student2 數學 80 student2 英語 100 轉換為 語文 數學 英語 s...

ORACLE 單行函式 轉

1.數字函式 abs 取絕對值 power 乘方 ln 10為底數取0 sqrt 平方根 exp e的n次乘方 log m,n m為底數n取0 數 算函式 acos atan atan2 cos cosh sign sin sinh tan tanh ceil 大於或等於取整數 floor 小於或等...