hive 包含操作(left semi join)(left outer join = in)迪卡爾積


目前hive不支持 in或not in 中包含查詢子句的語法,所以只能通過left join實現。

假設有一個登陸表login(當天登陸記錄,只有一個uid),和一個用戶注冊表regusers(當天注冊用戶,字段只有一個uid),這兩個表都包含一個字段,uid。

 

in查詢

如果要查詢當天登陸的注冊用戶,需要用in查詢,hive sql如下:

select login.uid from login left outer join regusers on login.uid=regusers.uid where regusers.uid is not null

如果login表和regusers表按天分區,字段是dt,那么查詢2013年1月1號當天登陸的注冊用戶,hive sql如下:

select login.uid from login day_login left outer join 
   (select uid from regusers where dt='20130101') day_regusers
on day_login.uid=day_regusers.uid where day_login.dt='20130101' and day_regusers.uid is not null

 

not in查詢

如果要查詢當天登陸的老用戶(這里假設非當天注冊用戶就是老用戶),需要用not in查詢,hive sql如下:

select login.uid from login left outer join regusers on login.uid=regusers.uid where regusers.uid is null;

如果login表和regusers表按天分區,字段是dt,那么查詢2013年1月1號當天登陸的老用戶,hive sql如下:

select login.uid from login day_login left outer join 
   (select uid from regusers where dt='20130101') day_regusers
on day_login.uid=day_regusers.uid where day_login.dt='20130101' and day_regusers.uid is null;

 


LEFT SEMI JOIN 是 IN/EXISTS 子查詢的一種更高效的實現。

Hive 當前沒有實現 IN/EXISTS 子查詢,所以你可以用 LEFT SEMI JOIN 重寫你的子查詢語句。LEFT SEMI JOIN 的限制是, JOIN 子句中右邊的表只能在 

 

ON 子句中設置過濾條件,在 WHERE 子句、SELECT 子句或其他地方過濾都不行。

 

  SELECT a.key, a.value

  FROM a

  WHERE a.key in

   (SELECT b.key

    FROM B);

可以被重寫為:

   SELECT a.key, a.val

   FROM a LEFT SEMI JOIN b on (a.key = b.key)


笛卡爾積

Hive本身是不支持笛卡爾積的,不能用select T1.*, T2.* from table_1, table_2這種語法。但有時候確實需要用到笛卡爾積的時候,可以用下面的語法來實現同樣的效果:

select T1.*, T2.* from (select * from table1) T1 join (select * from table2) T2 on 1=1;

其中on 1=1是可選的,注意在Hive的Strict模式下不能用這種語法,需要先用set hive.mapred.mode=nonstrict;設為非strict模式就可以用了。


免責聲明!

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



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