2017-05-05 5 views
1
の任意の一意の列/タイムスタンプなしで更新/挿入/削除されたレコードを見つけ、ベーステーブルにそれを追加するための2つのハイブテーブル

をBASE_TABLE(ソースから日01負荷)を比較Hadoopの

**Id Name City  Country** 
7682 Stuart Frankfurt Germany 
8723 Micke Paris  France 
2355 Niki New york USA 
2097 Deny Italy  Rome 

NEW_TABLE(ソースから日02負荷)

**Id Name City  Country** 
7682 Stuart *Darmstadt* Germany 
8723 Micke Paris  France 
2355 Niki New york USA 
*9057 Bony Prague  Prague* 

上記2つのテーブルを比較以下の3つの変化が見られる。

  1. レコードIDが7682の市名は
  2. レコードID 2097が日02負荷に削除された日02負荷にダルムシュタットに変更し、それは、ID 9057上で挿入日01負荷
  3. 新規レコードに存在しました日02負荷

上記のすべての3つの変更はBASE_TABLE

に取り込ま及び添付する必要があります3つの記録以下は3210

7682 Stuart Darmstadt Germany 
2097 Deny Italy  Rome 
9057 Bony Prague  Prague 

BASE_TABLE出力デイ02追加した後、比較ですから捕獲されなければならない私は、インサートと削除されたレコードを取得することができています

**Id Name City  Country** 
7682 Stuart Frankfurt Germany 
8723 Micke Paris  France 
2355 Niki New york USA 
2097 Deny Italy  Rome 
*7682 Stuart Darmstadt Germany* 
*2097 Deny Italy  Rome* 
*9057 Bony Prague  Prague* 

変更SQL結合を使用していますが、更新されたレコードを取得できません。更新されたレコードを取得するために、私はローカルにファイルをlinuxにコピーして比較をしましたが、大量のデータには適していませんでした。誰もこのタイプのシナリオを扱う際にあなたの経験を共有できますか?

+0

要求された出力は、いかなる意味にコメントを –

+0

感謝を作成しません。比較後に必要な正確な出力(3レコード)を追加しました。 – kumsgs

+0

これは私の2つの答えで分かるように、すでに明らかです。 (挿入/削除/更新)操作の指示なしにdiffを取得する点と、diffを基本表に追加する点は何かが明確ではありません。 –

答えて

0
select  inline 
      (
       array 
       (
        case 
         when n.id is null then struct(b.*) 
         else struct (n.*) 
        end 
       ) 
      ) 

from     base_table as b 
      full join new_table as n 
      on   n.id = b.id 

where  b.id is null 
     or n.id is null 
     or struct(b.*) not in (struct(n.*)) 

+------+--------+-----------+---------+ 
| col1 | col2 | col3 | col4 | 
+------+--------+-----------+---------+ 
| 2097 | Deny | Italy  | Rome | 
| 7682 | Stuart | Darmstadt | Germany | 
| 9057 | Bony | Prague | Prague | 
+------+--------+-----------+---------+ 
+0

お返事ありがとうございます。上記のクエリで更新レコードがどのように処理されるかについての説明を追加できますか? – kumsgs

+0

'struct(*)'は、レコードのすべてのフィールドから組み合わされた構造体です。 'struct(b。*)not in(struct(n。*))'はサポートされていない 'struct(b。*)!= struct(n。*)'の回避策です。 2つのレコードが同じ 'id'を持つが、' struct(b。*)!= struct(n。*) 'を持つ場合は、レコード間に違いがあるため、更新します。 –

0
select  inline(array(rec)) 

from  (select  max(struct(tab,rec)).col2 as rec 

      from  (   select 1 as tab,id,struct(*) as rec from base_table 
         union all select 2 as tab,id,struct(*) as rec from new_table 
         ) t 

      group by id 

      having  count(*) = 1 
        or min(rec) not in (max(rec)) 
      ) t 

+------+--------+-----------+---------+ 
| col1 | col2 | col3 | col4 | 
+------+--------+-----------+---------+ 
| 2097 | Deny | Italy  | Rome | 
| 7682 | Stuart | Darmstadt | Germany | 
| 9057 | Bony | Prague | Prague | 
+------+--------+-----------+---------+ 
+0

お返事ありがとうございます。上記のクエリで更新レコードがどのように処理されるかについての説明を追加できますか? – kumsgs

+0

'struct(*)'は、レコードのすべてのフィールドから組み合わされた構造体です。 'min(rec)not(max(rec))'はサポートされていない 'min(rec)!= max(rec)'の回避策です。レコードのグループが同じ 'id'を持つが、' min(rec)!= max(rec) 'を持っていれば、セット内の少なくとも異なるレコードが存在するため、更新されます。 –