大家好,又见面了,我是全栈君。
在Oracle中minus运算的主要功能是: 在进行两个表格或者两个查询结果的时候,返回在第一个表格/查询结果中与第二个表格/查询结果不同样的记录。
结果不同样的记录包括两种情况:A,B 表中某一行的内容不同和A表中的数据在B表中不存在。总之返回的是A表的数据。
Hive中没有实现minus功能的函数,仅仅好分步实现。
一、找出在A表中的数据在B表中不存在的数据
insert overwrite table tmp_A partition(name=’A_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 A=“”;
String B=“”;
public Text evaluate(String… strs){
for(int i=0;i<strs.length/2;i++){
A=A+strs[i];
}
for(int i=strs.length/2;i<strs.length;i++){
B=B+strs[i];
}
if(A.replace(” “, “”).equals(B.replace(” “, “”))){
return new Text(“NULL”);
}else{
return new Text(strs[0].replace(” “, “”));
}
}
相应的查询例如以下:
insert overwrite table tmp_A_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 A)minus (select * from B)的数据。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/116059.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...