Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
I join nelle visualizzazioni delle metriche arricchiscono i dati di origine con attributi di tabelle correlate. Supportano join diretti tra una tabella dei fatti e le tabelle delle dimensioni (schema a stella), join a più passaggi tra tabelle delle dimensioni normalizzate (schema a fiocco di neve) e join uno-a-molti che aggregano i dati provenienti dalle tabelle correlate. Per impostazione predefinita, tutti i join sono molti a uno, quindi ogni riga di origine corrisponde al massimo a una riga nella tabella collegata.
Join dello schema a stella
In uno schema a stella, source è la tabella dei fatti e si collega a una o più tabelle delle dimensioni utilizzando un LEFT OUTER JOIN. Le visualizzazioni delle metriche si uniscono alle tabelle dei fatti e delle dimensioni necessarie per la query specifica, in base ai campi e alle misure selezionati.
Specificare le colonne join usando una on clausola (espressione booleana) o una using clausola (nomi di colonna condivisa). Il join deve basarsi su una relazione da molti a uno. In caso di molti-a-molti, il motore seleziona la prima riga corrispondente dalla tabella delle dimensioni unita.
Nell'esempio seguente la orders tabella dei fatti viene unita alla tabella delle customer dimensioni con una on clausola , che accetta un'espressione booleana:
version: 1.1
source: samples.tpch.orders
joins:
# The on clause supports a Boolean expression
- name: customer
source: samples.tpch.customer
on: source.o_custkey = customer.c_custkey
fields:
# Field referencing a join column using dot notation
- name: Customer name
expr: customer.c_name
- name: Customer market segment
expr: customer.c_mktsegment
measures:
# Measure referencing a join column
- name: Total revenue
expr: SUM(o_totalprice)
- name: Order count
expr: COUNT(1)
Quando le colonne join hanno lo stesso nome in entrambe le tabelle, usare una using clausola anziché una on clausola . La clausola using accetta un array di nomi di colonna presenti sia nella tabella di origine sia nella tabella combinata. Nessun set di dati nel samples catalogo include tabelle che condividono un nome di colonna join, pertanto nell'esempio seguente vengono usati nomi di tabella segnaposto e di colonna per illustrare la sintassi:
joins:
- name: customer
source: catalog.schema.customer
using:
- customer_id
Annotazioni
In una on clausola, source riferisce alla tabella di origine della vista metrica e il join name fa riferimento alle colonne della tabella unita. Ad esempio, source.o_custkey = customer.c_custkey unisce la colonna o_custkey della tabella di origine alla colonna customer della tabella c_custkey. Se non viene specificato alcun prefisso, per impostazione predefinita, il riferimento è alla tabella unita.
Join dello schema Snowflake
Uno schema snowflake estende uno schema star normalizzando le tabelle delle dimensioni e collegandole alle sottodimensioni. Verrà creata una struttura di unione a più livelli.
Per definire uno schema snowflake:
- Creare una visualizzazione metrica.
- Aggiungere join di primo livello (schema star).
- Eseguire un join con altre tabelle delle dimensioni.
- Rendere disponibili gli attributi annidati aggiungendo campi nella visualizzazione.
Nell'esempio seguente viene usato il set di dati TPC-H per illustrare uno schema snowflake che mostra la gerarchia geografica degli ordini. L'esempio unisce la tabella degli ordini ai clienti, quindi alle nazioni (paesi o aree geografiche) e infine alle aree geografiche (continenti). Il set di dati TPC-H è disponibile nel catalogo samples nell'area di lavoro Azure Databricks.
source: samples.tpch.orders
joins:
- name: customer
source: samples.tpch.customer
on: source.o_custkey = customer.c_custkey
joins:
- name: nation
source: samples.tpch.nation
on: customer.c_nationkey = nation.n_nationkey
joins:
- name: region
source: samples.tpch.region
on: nation.n_regionkey = region.r_regionkey
fields:
- name: clerk
expr: o_clerk
- name: customer
expr: customer
comment: returns the full customer row as a struct
- name: customer_name
expr: customer.c_name
- name: nation
expr: customer.nation
- name: nation_name
expr: customer.nation.n_name
Cardinalità del join
Il campo cardinality in un join controlla la relazione tra la tabella di origine e la tabella collegata. Questo campo determina come il motore elabora le misure che fanno riferimento alle colonne della tabella unita.
La tabella seguente confronta le due cardinalità supportate:
| Property |
many_to_one (impostazione predefinita) |
one_to_many |
|---|---|---|
| Righe corrispondenti per riga di origine | Al massimo uno | Zero o più |
| Uso tipico | Ricerca dimensioni | Espansione dei dati |
Consentito in fields |
Sì | NO |
Consentito in measures |
Sì | Sì |
Giunzioni da molti a uno
Molti-a-uno è la cardinalità predefinita. Ogni riga nella sorgente corrisponde al massimo a una riga della tabella risultante dal join, quindi la tabella risultante funge da tabella di ricerca per le dimensioni. È possibile omettere il campo cardinality per join molti-a-uno, oppure specificare cardinality: many_to_one esplicitamente.
Sia i campi sia le misure possono fare riferimento alle colonne di una join molti-a-uno usando la notazione con il punto (ad esempio, customer.c_name).
Dichiara vincoli di join con rely
L'impostazione rely.at_most_one_match: true dichiara che il join non ha alcun fan-out sul lato "uno":
- In un join di tipo molti-a-uno, ogni riga di origine corrisponde ad al massimo una riga nella tabella unita.
- In un join uno-a-molti ogni riga unita corrisponde al massimo a una riga di origine.
Questa dichiarazione consente al motore di ignorare i join non necessari e ridurre i dati analizzati, in particolare per le query che applicano filtri ai campi della tabella collegata. Databricks consiglia di impostare rely su entrambe le cardinalità quando il vincolo è soddisfatto.
Avvertimento
Imposta at_most_one_match: true solo quando la relazione sussiste effettivamente. Questa proprietà non viene convalidata in fase di esecuzione. Se il lato asserito produce un fan-out, le misure restituiscono risultati non corretti.
L'esempio seguente collega orders a customer con rely abilitato:
version: 1.1
source: samples.tpch.orders
joins:
- name: customer
source: samples.tpch.customer
on: source.o_custkey = customer.c_custkey
rely:
at_most_one_match: true
fields:
- name: Customer name
expr: customer.c_name
- name: Customer market segment
expr: customer.c_mktsegment
measures:
- name: Total revenue
expr: SUM(o_totalprice)
- name: Order count
expr: COUNT(1)
Vedere Ottimizzare i join con rely per il riferimento completo del campo rely.
Join uno-a-molti
Impostare cardinality: one_to_many per consentire a una singola riga di origine di essere associata a più righe nella tabella risultante dal join. Ciò trasforma quella tabella in una fonte di fatti che il motore aggrega in modo indipendente al livello di granularità di origine.
Annotazioni
I join uno-a-molti richiedono Databricks Runtime 18.1 o superiore e la specifica YAML 1.1. Vedere Disponibilità delle funzionalità di visualizzazione delle metriche.
Un join uno-a-molti consente a un'unica vista metrica di misurare dati fattuali a diversi livelli di granularità, ad esempio ordini per cliente o eventi per account, senza duplicare le righe di origine nei risultati della query. L'origine funge da colonna vertebrale dimensionale: ogni entità viene visualizzata esattamente una volta, indipendentemente dal numero di righe corrispondenti presenti nella tabella unita.
Annotazioni
Se una tabella che unisci ha una ARRAY colonna o, MAP appiattila nella source sua tabella prima di unirla. Vedi Resolve array e mappe nella fonte.
Esempio di join uno-a-molti
L'esempio seguente usa customer come sorgente e unisce orders a cardinality: one_to_many. Un many_to_one join con nation fornisce il campo nation_name. Qualifica il lato sorgente di ogni condizione di join con source. in modo che il riferimento venga ricondotto alla tabella sorgente della vista metrica. Entrambi i join impostati rely.at_most_one_match: true: nel nation join asserisce che ogni cliente ha al massimo una nazione e al orders join asserisce che ogni ordine appartiene al massimo un cliente. Vedi Dichiarare vincoli di join con rely.
version: 1.1
source: samples.tpch.customer
joins:
- name: nation
source: samples.tpch.nation
on: nation.n_nationkey = source.c_nationkey
rely:
at_most_one_match: true
- name: orders
source: samples.tpch.orders
on: orders.o_custkey = source.c_custkey
cardinality: one_to_many
rely:
at_most_one_match: true
fields:
- name: customer_name
expr: c_name
- name: nation_name
expr: nation.n_name
measures:
- name: customer_count
expr: count(*)
- name: order_count
expr: count(orders.o_orderkey)
- name: total_order_revenue
expr: sum(orders.o_totalprice)
In questa vista, customer_count conta le righe nella tabella di origine customer , mentre order_count e total_order_revenue aggregano le righe dal orders ramo. Un cliente con due ordini restituisce un order_count valore pari a 2 mentre customer_count rimane 1, che conferma che le righe di origine non sono duplicate. Un cliente senza ordini viene ancora visualizzato nei risultati, con un valore order_count pari a 0 e un oggetto NULLtotal_order_revenue.
Join uno-a-molti annidati
Per misurare i fatti che sono due o più livelli al di sotto dell'origine, annidare join uno-a-molti. Tutti i join in un sottoalbero uno-a-molti devono condividere la stessa cardinalità, quindi un padre uno-a-molti non può avere un figlio molti-a-uno. Fare riferimento a una colonna in un join annidato tramite il relativo percorso completo con punti attraverso i nomi dei join.
L'esempio seguente annida lineitem in orders in modo che una singola vista a granularità cliente possa contare sia gli ordini sia le righe d'ordine:
version: 1.1
source: samples.tpch.customer
joins:
- name: orders
source: samples.tpch.orders
on: orders.o_custkey = source.c_custkey
cardinality: one_to_many
joins:
- name: lineitem
source: samples.tpch.lineitem
on: lineitem.l_orderkey = orders.o_orderkey
cardinality: one_to_many
fields:
- name: customer_name
expr: c_name
measures:
- name: order_count
expr: count(distinct orders.o_orderkey)
- name: line_item_count
expr: count(orders.lineitem.l_linenumber)
- name: total_line_revenue
expr: sum(orders.lineitem.l_extendedprice)
Le misure fanno riferimento alle colonne nidificate con il relativo percorso completo tramite i nomi di join, ad esempio orders.lineitem.l_extendedprice, perché lineitem è raggiungibile solo tramite orders. Usare count(distinct orders.o_orderkey) anziché un semplice count per il conteggio degli ordini: ogni ordine si suddivide in più voci di riga, quindi un semplice conteggio conterebbe un ordine una volta per ogni voce di riga.
Join uno-a-molti affiancate
Definire più join uno-a-molti allo stesso livello per misurare le origini dei fatti indipendenti da una singola visualizzazione. Il motore aggrega separatamente i join fratelli e poi li combina, per cui le rispettive righe non si moltiplicano mai tra loro. Gli elementi di pari livello al livello superiore possono combinare liberamente le cardinalità, quindi un join sulla dimensione many_to_one e un join sui fatti one_to_many possono coesistere allo stesso livello.
L'esempio seguente usa nation come sorgente e aggiunge due rami indipendenti uno a molti, customer e supplier:
version: 1.1
source: samples.tpch.nation
joins:
- name: customer
source: samples.tpch.customer
on: customer.c_nationkey = source.n_nationkey
cardinality: one_to_many
- name: supplier
source: samples.tpch.supplier
on: supplier.s_nationkey = source.n_nationkey
cardinality: one_to_many
fields:
- name: nation_name
expr: n_name
measures:
- name: customer_count
expr: count(customer.c_custkey)
- name: supplier_count
expr: count(supplier.s_suppkey)
- name: customers_per_supplier
expr: count(customer.c_custkey) / count(supplier.s_suppkey)
La misura customers_per_supplier divide due aggregazioni indipendenti dopo che il motore combina ciascuna al livello di granularità della query. È possibile combinare misure provenienti da origini diverse con aritmetica, ma una singola funzione di aggregazione deve fare riferimento a colonne di una sola origine.
Collegare più tabelle dei fatti con una tabella ponte
Una vista metrica modella una singola tabella dei fatti unita alle tabelle delle dimensioni. Per combinare le misure di due o più tabelle dei fatti con granularità diverse, definire una tabella ponte che elenchi le combinazioni valide delle dimensioni condivise dai fatti, direttamente nella source vista metrica. Ad esempio, il samples.tpch fatto lineitem di spedizione (granularità: riga d'ordine) e il fatto partsupp di fornitura (granularità: componente e fornitore) condividono entrambe le dimensioni componente e fornitore.
Un bridge rende esplicito il set di combinazioni di dimensioni valide, in modo che i risultati delle query rimangano prevedibili. La visualizzazione metrica restituisce solo le combinazioni dichiarate valide anziché dedurrle per ogni query. Impostare cardinality: one_to_many per ogni join tra fatti in modo che il motore aggreghi ogni fatto in modo indipendente rispetto al bridge condiviso, senza generare fan-out né doppi conteggi.
Per creare il bridge, definirlo come una query SQL nella vista metrica source, unire ogni tabella dei fatti a esso in base alle colonne condivise, quindi definire i campi sulle colonne della dimensione condivisa e le misure su ciascun fatto. Utilizzare un oggetto CROSS JOIN quando ogni combinazione delle dimensioni condivise è valida:
version: 1.1
source: SELECT * FROM samples.tpch.part CROSS JOIN samples.tpch.supplier
filter: s_suppkey IN (11315, 42920) AND p_partkey IN (30419, 80418)
joins:
- name: lineitem
source: samples.tpch.lineitem
on: source.p_partkey = lineitem.l_partkey AND source.s_suppkey = lineitem.l_suppkey
cardinality: one_to_many
- name: partsupp
source: samples.tpch.partsupp
on: source.p_partkey = partsupp.ps_partkey AND source.s_suppkey = partsupp.ps_suppkey
cardinality: one_to_many
fields:
- name: part_name
expr: p_name
- name: part_brand
expr: p_brand
- name: part_type
expr: p_type
- name: part_size
expr: p_size
- name: manufacturer
expr: p_mfgr
- name: supplier_name
expr: s_name
measures:
- name: lineitem_count
expr: COUNT(lineitem.*)
- name: total_quantity_sold
expr: SUM(lineitem.l_quantity)
- name: gross_revenue
expr: SUM(lineitem.l_extendedprice)
- name: net_revenue
expr: SUM(lineitem.l_extendedprice * (1 - lineitem.l_discount))
- name: distinct_orders
expr: COUNT(DISTINCT lineitem.l_orderkey)
- name: available_quantity
expr: SUM(partsupp.ps_availqty)
- name: avg_supply_cost
expr: AVG(partsupp.ps_supplycost)
- name: total_supply_value
expr: SUM(partsupp.ps_availqty * partsupp.ps_supplycost)
Una misura su una tabella dei fatti conta solo i record i cui valori delle dimensioni condivise vengono visualizzati nel bridge. Le combinazioni che il bridge non include non contribuiscono ai risultati.
Quando vuoi solo le combinazioni che si verificano effettivamente, sostituisci source con un UNION (o FULL OUTER JOIN) delle coppie distinte di ciascun fatto, in modo che ciascun fatto contribuisca con i propri membri.
joins, fieldse measures rimangono invariati:
source: |
SELECT DISTINCT l_partkey AS p_partkey, l_suppkey AS s_suppkey FROM samples.tpch.lineitem
UNION
SELECT DISTINCT ps_partkey AS p_partkey, ps_suppkey AS s_suppkey FROM samples.tpch.partsupp
Restrizioni di join da uno a molti
-
I campi non possono fare riferimento a un join uno-a-molti: un campo deve corrispondere a un solo valore per ciascuna riga di origine. Poiché una colonna uno-a-molti può avere più valori per riga di origine, non è possibile usarla in una
fieldsdefinizione. Per usare una colonna di questo tipo come campo, imposta quella tabella come origine dati e unisci l'origine dati originale come joinmany_to_one. -
Una singola aggregazione non può estendersi su origini: ogni funzione di aggregazione deve fare riferimento a colonne da un'origine. L'aritmetica tra i risultati di due aggregazioni è consentita, ad esempio
count(orders.o_orderkey) / count(*), ma una singola funzione non può combinare colonne da due origini. - Un sottoalbero di join non può mescolare cardinalità: tutti i discendenti di un join uno-a-molti devono anch'essi essere uno-a-molti e tutti i discendenti di un join molti-a-uno devono essere molti-a-uno. Solo gli elementi di pari livello superiore possono combinare cardinalità.