2015-08-04 50 views
5

Ho due tabelle, tabella1 e tabella2. Ciascuno con le stesse colonne:Confronto di due tabelle per l'uguaglianza in HIVE

key, c1, c2, c3 

voglio controllare per vedere se queste tabelle sono uguali a vicenda (hanno le stesse righe). Finora ho questi due query (<> = non uguale a HIVE):

select count(*) from table1 t1 
left outer join table2 t2 
on t1.key=t2.key 
where t2.key is null or t1.c1<>t2.c1 or t1.c2<>t2.c2 or t1.c3<>t2.c3 

E

select count(*) from table1 t1 
left outer join table2 t2 
on t1.key=t2.key and t1.c1=t2.c1 and t1.c2=t2.c2 and t1.c3=t2.c3 
where t2.key is null 

Quindi la mia idea è che, se un conteggio a zero viene restituito, le tabelle sono gli stessi . Tuttavia, sto ottenendo un conteggio zero per la prima query e un conteggio diverso da zero per la seconda query. In che modo differiscono esattamente? Se c'è un modo migliore per controllare questo, fammelo sapere.

risposta

8

Il primo esclude righe dove t1.c1, t1.c2, t1.c3, t2.c1, t2.c2 o t2.c3 è nullo. Ciò significa che stai effettivamente facendo un join interiore.

Il secondo troverà le righe che esistono in t1 ma non in t2.

Per trovare anche le righe che esistono in t2 ma non in t1 è possibile eseguire un join esterno completo. Il seguente SQL presuppone che tutte le colonne sono NOT NULL:

select count(*) from table1 t1 
full outer join table2 t2 
on t1.key=t2.key and t1.c1=t2.c1 and t1.c2=t2.c2 and t1.c3=t2.c3 
where t1.key is null /* this condition matches rows that only exist in t2 */ 
    or t2.key is null /* this condition matches rows that only exist in t1 */ 
+0

Per il primo, se so che nessuno dei le colonne sono nulle, questo implica che controlli se i tavoli sono uguali? Non sono completamente sicuro delle implicazioni della tua prima affermazione. @KlasLindback – Danzo

+0

@Danzo Sì, è sufficiente che una delle tabelle non abbia valori nulli. –

3

Se si desidera controllare i duplicati e le tabelle hanno esattamente la stessa struttura e le tabelle non hanno duplicati al loro interno, allora si può fare:

select t.key, t.c1, t.c2, t.c3, count(*) as cnt 
from ((select t1.*, 1 as which from table1 t1) union all 
     (select t2.*, 2 as which from table2 t2) 
    ) t 
group by t.key, t.c1, t.c2, t.c3 
having cnt <> 2; 

Ci sono vari modi che puoi rilassare le condizioni nel primo paragrafo, se necessario.

Si noti che questa versione funziona anche quando le colonne hanno valori NULL. Questi potrebbero causare il problema con i tuoi dati.

+0

Quindi questo controlla i duplicati, ma come fa a garantire che le tabelle corrispondano? Dire che la tabella 1 ha una riga (1,2,3,4) e la tabella 2 ha una riga (1,2,3,5). Questa query restituirà entrambe queste righe perché cnt = 1? @GordonLinoff – Danzo

+0

@Danzo. . . Sì. Questa query restituirà tutte le righe che non hanno corrispondenza nell'altra tabella. Puoi renderlo un sottoquery e fare un 'count (*)' per vedere se ci sono tali righe. –

-2

utilizzare un operatore MINUS:

SELECT count(*) FROM 
    (SELECT t1.c1, t1.c2, t1.c3 from table1 t1 
    MINUS 
    SELECT t2.c1, t2.c2, t2.c3 from table2 t2) 
+1

Qualche idea su come lo faresti in HIVEQL? @AHocevar – Danzo

+0

E questo è il motivo per cui ho bisogno di più caffè ... Non c'è un operatore MINUS in HiveQL, dovrai andare con un join esterno completo come suggerito da @Klas Lindbäck –

0

un'altra variante

select c1-c2 "different row counts" 
, c1-c3 "mismatched rows" 
from 
(select count(*) c1 from table1) 
,(select count(*) c2 from table2) 
,(select count(*) c3 from table1 t1, table2 t2 
    where t1.key= t2.key 
    and T1.c1=T2.c1) 
+0

contando non solo se la chiave corrisponde ma anche il valore in c1 – Randy

0

Prova con la clausola:

With cnt as(
    select count(*) cn1 from table1 
    ) 
    select 'X' from dual,cnt where cnt.cn1 = (select count(*) from table2); 
0

lo consiglio non utilizzando qualsiasi congiunge a cercare di confrontare tavoli:

  • esso è piuttosto costose operazioni quando le tabelle sono grandi (che è spesso il caso in alveare)
  • può dare problemi durante alcune righe/"uniscono tasti" vengono ripetute

(e può anche essere poco pratico quando i dati sono in diversi cluster/datacenter/nuvole).

Invece, penso che l'utilizzo di un approccio di checksum e il confronto dei checksum di entrambe le tabelle sia il migliore.

ho sviluppato uno script Python che ti permette di fare facilmente tale confronto, e vedere le differenze in un browser web:

https://github.com/bolcom/hive_compared_bq

Spero che può aiutare!

0

Una soluzione semplice consiste nel fare un join interno. Supponiamo di avere due tabelle hive, ovvero table1 e table2. Entrambi i tavoli hanno la stessa colonna, col1, col2 e col3. Il numero di righe dovrebbe essere uguale. Allora il comando sarà il seguente

**

select count(*) from table1 
inner join table2 
on table1.col1 = table2.col1 
and table1.col2 = table2.col2 
and table1.col3 = table2.col3 ; 

**

Se il valore di uscita è uguale numero di righe nella tabella 1 e table2, quindi tutte le colonne ha lo stesso valore, Se tuttavia il conteggio delle uscite è inferiore a quello di alcuni dati diversi.