Hive實現oracle的Minus函數


在Oracle中minus運算的主要功能是: 在進行兩個表格或者兩個查詢結果的時候,返回在第一個表格/查詢結果中與第二個表格/查詢結果不同樣的記錄。

結果不同樣的記錄包括兩種情況:A,B 表中某一行的內容不同和A表中的數據在B表中不存在。總之返回的是A表的數據。

Hive中沒有實現minus功能的函數,僅僅好分步實現。

一、找出在A表中的數據在B表中不存在的數據

insert overwrite table tmp_A partition(name='_innot_B')

select 

                  a.*

from A a left outer join  B b on (a.id = b.id)  where b.id is NULL; 

二、找出在A表和B表都存在但內容不同的數據

UDF函數例如以下:

public class Minus extends UDF{

String ="";

String ="";

public Text evaluate(String... strs){

for(int i=0;i<strs.length/2;i++){

=+strs[i];

}

for(int i=strs.length/2;i<strs.length;i++){

=+strs[i];

}

if(.replace(" """).equals(.replace(" """))){

return new Text("NULL");

}else{

return new Text(strs[0].replace(" """));

}

}

相應的查詢例如以下:

insert overwrite table tmp__diff

select iminus(

                       a.*,b.*

     ) from A a join B b on (a.id=b.id);

上面的sql會執行Minus的java程序,改程序語句中有循環。假設數據量非常大非常耗時間。job進度卡着不動。也能夠使用hive自帶的函數實現

insert overwrite table tmp_A_diff
select if(
        regexp_replace(
                  concat(                        
                        a.*
                        ),
                          " ","")
       =
        regexp_replace(
                 concat(
                        b.*
                        ),
                          " ","")
       ,NULL,b.id)
    from A a
             join 
         B b 
             on (a.id=b.id);

這樣效率好些。


tmp_A_diff存儲的是A表和B表都存在但內容不同的數據的id和一些“NULL”

依據id獲得每行數據

insert overwrite table tmp_A partition(name="A_in_B")

select            a.*

from tmp_A_diff b join A a on (a.id=b.id);

如今tmp_A中分區A_innot_B和分區A_in_B的數據就是oracle中(select * from Aminus (select * from B)的數據。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM