2017-06-21 68 views
0

集合結果蜂房比較我有一個表(例如稱爲)所示:與來自子查詢

------------- 
|Name|ID|...| 
------------- 
|A |1 |...| 
|A |2 |...| 
|A |3 |...| 
|B |1 |...| 
|B |2 |...| 
|C |1 |...| 
------------- 

所以每個名稱可以具有多個條目,每個條目有一個遞增ID(其由進行分區,名稱,因爲您現在可能已經知道了)。現在,我有另一個表(稱爲目的地),其中我從來源表中加載,例如,每日批次。不過,我只想從來源加載增量,所以如果我目的地表是這樣的:

------------- 
|Name|ID|...| 
------------- 
|A |1 |...| 
|A |2 |...| 
|B |1 |...| 
------------- 

我只想區別從來源複製到目的地,這將是:

------------- 
|Name|ID|...| 
------------- 
|A |3 |...| 
|B |2 |...| 
|C |1 |...| 
------------- 

其他原因我不能使用時間戳或爲此負,所以唯一的辦法,找到差異將通過獲取MAX(ID )每個名稱和僅檢索條目> MAX(ID)每個名稱

最快的實施方法是,通過其準備所有MAX(ID)爲每個名稱子查詢,並用它來消除小ID S:

SELECT s.* FROM Source s 
LEFT JOIN (
SELECT d.NAME, MAX(d.ID) AS MAX_ID 
FROM Dest d 
GROUP BY d.NAME) n 
ON s.NAME = n.NAME 
WHERE s.ID > COALESCE(n.MAX_ID,0) 

然而,由於表中有很多條目,我相信這不會表現的很好,除非Hive能夠自動優化它,但我不確定。

我希望做的是這樣的:對於所有的條目

SELECT s.* FROM Source s 
WHERE s.ID > (SELECT COALESCE(MAX(d.ID),0) 
       FROM Dest d 
       WHERE d.NAME = s.NAME) 

這樣我會避免計算MAX(ID),並且將只計算其當前名稱 。但在Hive中顯然是不可能的。

所以我的問題是,什麼是在Hive中實現這種增量檢測的最好和最有效的方法?

回答

0

爲什麼不使用left joinwhere

SELECT s.* 
FROM Source s LEFT JOIN 
    Dest d 
    ON s.NAME = d.NAME AND s.ID = d.ID 
WHERE d.NAME IS NULL; 

如果你真的需要做到這一點使用的最大ID從Dest,然後用GROUP BY你的方法應該在蜂巢被罰款。

+0

原因是因爲實際** Source **表是一種歷史歸檔,特別是每次將某些ID添加到名稱時,以前的ID也會被添加。例如。昨天的參賽作品** 1,2 **名稱** A **被添加,今天的參賽作品** 1,2,3 **添加了名稱** A **,因此添加了** 1,2 **再次,然後*​​ 3 **。這使得您很難使用您的方法或時間戳。我的「GROUP BY」方法在數百萬條記錄中仍然表現良好,還是有更好的方法,就像第二種方法的替代方法一樣? – Johnny16

+0

@ Johnny16。 。 。正如你所描述的那樣,'left join'仍然可以工作(即使有重複)。不過,它確實使'group by'更加可口。 –