SELECTSELECT

SELECT

Escludere e rinominare colonne con SELECT * in Snowflake

By Ian WhitestoneDec 17, 20225 min read

Questa pagina è disponibile anche in English, Deutsch, Español, Français, 日本語 e Português.

Perché servono EXCLUDE e RENAME?

Con la release di novembre 2022, Snowflake ha annunciato in sordina una nuova sintassi SQL davvero interessante: EXCLUDE e RENAME, che permette di rimuovere e rinominare colonne specifiche nelle query in stile SELECT . Una novità di particolare rilievo, perché nei workflow SQL non di produzione capita spessissimo di lanciare query esplorative in stile `SELECT ` come:

select *
from table
where id = 5

Lo si fa di solito per ispezionare un record o un sottoinsieme di record. Ma cosa succede quando si vuole escludere una colonna specifica (ad esempio una grossa colonna di testo) oppure rinominarla? Tocca elencare manualmente tutte le colonne desiderate, applicando le eventuali rinomine con la classica sintassi AS:

select
  column_1,
  column_2,
  column_3 as column_3_renamed,
  column_4,
  column_5,
  column_6,
  column_7,
  column_8,
  column_9, -- columns 10 and 11 are intentionally left out
  column_12
from table
where id = 5

Non proprio l'ideale quando servono risposte rapide.

Come escludere colonne in una query SELECT \* in Snowflake

Invece di digitare ogni singola colonna, una richiesta ricorrente 1 da parte degli utenti è la possibilità di indicare un sottoinsieme di colonne da escludere dalla tabella. In molti casi è un approccio decisamente più rapido da scrivere, perché le colonne da escludere sono spesso molte meno di quelle da includere. A partire dalla versione 6.37 di Snowflake, è possibile aggiungere una clausola EXCLUDE alle query in stile SELECT *, specificando una o più colonne che non si vogliono restituire:

select
  *
  exclude(column_10, column_11)
from table
where id = 5

La stessa sintassi funziona anche per escludere una singola colonna:

select
  *
  exclude (column_10)
from table
where id = 5

Le parentesi sono facoltative quando si esclude una sola colonna. Lo stesso SQL può essere riscritto così:

select
  *
  exclude column_10
from table
where id = 5

Usare EXCLUDE di Snowflake con più tabelle

Un altro caso d'uso tipico per l'esclusione delle colonne è il join tra più tabelle. Si immagini una query come questa 2:

select
  orders.*,
  customers.* exclude customer_id,
  items.* exclude order_id
from orders
join customers
  on orders.customer_id=customers.customer_id
join items
  on orders.order_id=items.order_id

In questo esempio l'output presenta due colonne order_id e due colonne customer_id, perché compaiono in più tabelle. Possiamo eliminarle facilmente modificando l'SQL così:

select
  orders.*,
  customers.* exclude customer_id,
  items.* exclude order_id
from orders
join customers
  on orders.customer_id=customers.customer_id
join items
  on orders.order_id=items.order_id

L'equivalente Snowflake della clausola EXCEPT di BigQuery e Databricks

La sintassi EXCLUDE di Snowflake è analoga a EXCEPT di BigQuery e Databricks:

-- Snowflake
select
  *
  exclude(column_10, column_11)
from table

-- BigQuery/Databricks
select
  *
  except(column_10, column_11)
from table

Chi conosce DuckDB riconoscerà che Snowflake adotta la stessa sintassi EXCLUDE già utilizzata da DuckDB. Entrambi i database hanno presumibilmente scelto di non riutilizzare la keyword EXCEPT per questa funzionalità, dato che è già impiegata nelle operazioni sugli insiemi.

Conviene usare EXCLUDE nel codice SQL di produzione?

Per quanto questa nuova sintassi sia ottima per velocizzare i workflow ad hoc, è sconsigliata nel codice SQL di produzione. Meglio essere espliciti su quali colonne si stanno selezionando: indicare per esteso tutti i nomi migliora la leggibilità e la tracciabilità. Chi legge il codice capisce subito quali colonne vengono usate e da quali tabelle. In più, gli errori diventano più chiari: se una colonna viene rimossa dalla tabella, il codice SQL fallisce immediatamente, anziché lasciare che sia un'applicazione downstream a sollevare un errore inatteso per una colonna mancante.

L'uso di EXCLUDE in Snowflake cambia il query plan o le prestazioni?

No. Usare la keyword EXCLUDE per rimuovere alcune colonne non produce un query plan né prestazioni diverse rispetto all'elenco esplicito di tutte le colonne. Lo può verificare lanciando entrambe le varianti su un dataset nel suo account Snowflake e confrontando il query profile di ciascuna query.

Come rinominare colonne in una query SELECT \* in Snowflake

Prima della nuova funzionalità RENAME, bastava la necessità di rinominare una sola colonna in una query SELECT * per essere costretti a elencarle tutte. Ora si possono selezionare tutte le colonne rinominandone solo un sottoinsieme:

select
  *
  rename (column_3 as column_3_renamed, column_5 as column_5_renamed)
from table
where id = 5

Decisamente meglio che elencare tutti i campi solo per rinominarne uno o due:

-- old method 👎
select
  column_1,
  column_2,
  column_3 as column_3_renamed,
  column_4,
  column_5 as column_5_renamed,
  column_6,
  ...
  column_12
from table
where id = 5

Come per EXCLUDE, il meccanismo vale anche per una singola colonna, con parentesi facoltative:

select
  *
  rename (column_3 as column_3_renamed)
from table
where id = 5

Combinare EXCLUDE e RENAME

EXCLUDE e RENAME si possono combinare facilmente, come nell'esempio seguente:

select
  *
  exclude(column_10, column_11)
  rename column_3 as column_3_renamed
from table
where id = 5

Decisamente meglio del codice all'inizio dell'articolo:

select
  column_1,
  column_2,
  column_3 as column_3_renamed,
  column_4,
  column_5,
  column_6,
  column_7,
  column_8,
  column_9, -- columns 10 and 11 are intentionally left out
  column_12
from table
where id = 5

Note

  1. Per rendere l'idea di quanto sia richiesta questa funzionalità, questa domanda su Stack Overflow, postata quasi 14 anni fa, conta 1,3 milioni di visualizzazioni e oltre 1.000 upvote.

  2. Un grazie a Nate Sooter per lo spunto di questo esempio, nato dal suo recente tweet!

Ian Whitestone·Co-founder & CEO di SELECT

Ian è Co-founder & CEO di SELECT, piattaforma SaaS per la gestione e l'ottimizzazione dei costi su Snowflake. Prima di fondare SELECT, ha guidato per 6 anni team full stack di data science ed engineering in Shopify e Capital One. In Shopify ha coordinato il lavoro di ottimizzazione del data warehouse e di miglioramento dell'osservabilità dei costi.