opendatasicilia / tansignari

"T'ansignari e t'appeddiri"
http://tansignari.opendatasicilia.it
Creative Commons Attribution 4.0 International
18 stars 10 forks source link

Unione di tabelle in modo che non si perdano dati #262

Closed pigreco closed 1 month ago

pigreco commented 1 month ago

Ho due tabelle che devo unire senza perdere righe , se facessi una left join perderei una riga 090003, se facessi una rigth join perderei una riga 090002: (campo unione COMUNE_IST)

tabella_03

COMUNE_IST Sup_03ha Cls_LivI_03
090002 6.167764657014888 5
090002 4418.695029356092 3
090002 476.4773446171668 2
090002 47.60749054979091 1
090003 2.986054141487481 5
090003 2040.7894682171927 3
090003 2560.784034003995 2
090003 143.04663460051736 1
090003 3.0119929195484842 0

tabella_08

COMUNE_IST Sup_08ha Cls_LivI_08
090002 4375.534226015951 3
090002 490.3999413012836 2
090002 83.01346186282966 1
090003 0.012633751875882445 0
090003 541.9179878095715 1
090003 1823.7816133090548 3
090003 2370.0713866133647 2
090003 3.072883214239986 5
090003 11.76167918463312 4

come ottenere la tabella unione?

COMUNE_IST Cls_LivI_03 Sup_08ha Sup_03ha
90002 3 4375.53422601595 4418.69502935609
90002 2 490.399941301284 476.477344617167
90002 1 83.0134618628297 47.6074905497909
90002 5 6.16776465701489
90003 1 541.917987809572 143.046634600517
90003 3 1823.78161330905 2040.78946821719
90003 2 2370.07138661336 2560.784034004
90003 5 3.07288321423999 2.98605414148748
90003 4 11.7616791846331

per ottenere la tabella di output ho fatto un outer join (su visidata) usando due attributi come campi correlati (COMUNE_IST e Sup_03ha o Sup_08ha) (COMUNE_IST e Cls_LivI_03 o Cls_LivI_08)

è la via corretta?

aborruso commented 1 month ago

@pigreco non capisco una cosa. Nelle due tabelle, hai enne volte lo stesso COMUNE_IST, e quindi se fai JOIN outer full, per 090002 avresti il prodotto cartesiano di 4 x 3, quindi 12 righe.

Con che criterio estrai le 4 del tuo output (non mi dire visidata), quale logica vuoi applicata?

aborruso commented 1 month ago

@pigreco ma tu vuoi in realtà soltanto concatenarli? Senza join?

Qualcosa come

COMUNE_IST Sup_03ha Cls_LivI_03 Sup_08ha Cls_LivI_08
090002 6.167764657014888 5
090002 4418.695029356092 3
090002 476.4773446171668 2
090002 47.60749054979091 1
090002 4375.534226015951 3
090002 490.3999413012836 2
090002 83.01346186282966 1
090003 2.986054141487481 5
090003 2040.7894682171927 3
090003 2560.784034003995 2
090003 143.04663460051736 1
090003 3.0119929195484842 0
090003 0.012633751875882445 0
090003 541.9179878095715 1
090003 1823.7816133090548 3
090003 2370.0713866133647 2
090003 3.072883214239986 5
090003 11.76167918463312 4
pigreco commented 1 month ago

ho usato come campi correlati due attributi per tabella (COMUNE_IST e Cls_LivI_03 o Cls_LivI_08)

aborruso commented 1 month ago

Ok, ti do una risposta rapida subito, poi con calma magari approfondiamo.

Ho rinominato il campo in entrambe in Cls_Liv e poi con Miller ad esempio è (ho rinominato tabelle in A e B):

mlr --csv join --ul --ur -j COMUNE_IST,Cls_Liv -f A.csv then unsparsify then sort -t COMUNE_IST B.csv >out.csv

Questo è insieme join left e right (--ul --ur) e quindi è un full outer.

COMUNE_IST Cls_Liv Sup_03ha Sup_08ha
090002 3 4418.695029356092 4375.534226015951
090002 2 476.4773446171668 490.3999413012836
090002 1 47.60749054979091 83.01346186282966
090002 5 6.167764657014888
090003 0 3.0119929195484842 0.012633751875882445
090003 1 143.04663460051736 541.9179878095715
090003 3 2040.7894682171927 1823.7816133090548
090003 2 2560.784034003995 2370.0713866133647
090003 5 2.986054141487481 3.072883214239986
090003 4 11.76167918463312
aborruso commented 1 month ago

In duckdb è SQL standard

duckdb --csv -c "
SELECT
  A.*,
  B.* EXCLUDE(COMUNE_IST, Cls_Liv)
FROM
  'A.CSV' A
  FULL OUTER JOIN 'B.CSV' B ON A.COMUNE_IST = B.COMUNE_IST
  AND A.Cls_Liv = B.Cls_Liv
ORDER BY
  A.COMUNE_IST" >out.csv
pigreco commented 1 month ago

Grazie mille(r) ricetta fatta e pubblicata

https://tansignari.opendatasicilia.it/ricette/csv-tsv/unire_tabelle_outer_join/