SELECTSELECT

SELECT

Excluir e renomear colunas com SELECT * no Snowflake

By Ian WhitestoneDec 17, 20225 min read

Esta página também está disponível em English, Deutsch, Español, Français, Italiano e 日本語.

Por que precisamos do EXCLUDE e do RENAME?

No release de novembro de 2022, o Snowflake anunciou discretamente uma nova sintaxe SQL bem interessante, EXCLUDE e RENAME, que permite remover e renomear colunas específicas em consultas do tipo SELECT . Isso é especialmente útil, já que é muito comum, em workflows SQL fora de produção, rodar consultas exploratórias no estilo `SELECT `, como:

select *
from table
where id = 5

Normalmente fazemos isso para investigar um registro específico ou um subconjunto de registros. Mas e quando você quer excluir uma coluna específica (como uma coluna de texto muito grande) ou renomear alguma delas? Aí não tem jeito: é preciso digitar todas as colunas desejadas, junto com as renomeações usando a sintaxe tradicional 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

Nada prático quando você precisa de respostas rápidas.

Como excluir colunas ao executar um SELECT \* no Snowflake?

Em vez de digitar coluna por coluna, um pedido recorrente 1 dos usuários é poder especificar um subconjunto de colunas a serem excluídas da tabela. Em muitos casos, isso é bem mais eficiente, já que o número de colunas a excluir costuma ser bem menor do que o número a incluir. A partir do release 6.37 do Snowflake, agora dá para incluir uma cláusula EXCLUDE em consultas SQL do tipo SELECT *, indicando uma ou mais colunas que você não quer que sejam retornadas:

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

Também é possível usar para excluir uma única coluna:

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

Os parênteses são opcionais quando se exclui uma única coluna. O SQL acima pode ser reescrito assim:

select
  *
  exclude column_10
from table
where id = 5

Usando o EXCLUDE do Snowflake com várias tabelas

Outra situação em que excluir colunas é útil é ao fazer join entre várias tabelas. Imagine uma consulta como esta 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

Neste exemplo, temos duas colunas order_id e duas colunas customer_id no resultado, porque elas aparecem em mais de uma tabela. Dá para excluí-las facilmente ajustando o SQL para:

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

O equivalente do Snowflake ao EXCEPT do BigQuery e do Databricks

A sintaxe EXCLUDE do Snowflake é parecida com o EXCEPT do BigQuery e do Databricks:

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

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

Para quem já conhece o DuckDB, o Snowflake adotou a mesma sintaxe EXCLUDE usada por ele. Provavelmente os dois bancos optaram por não usar a palavra-chave EXCEPT para essa funcionalidade porque ela já é usada em operações de conjunto.

Vale a pena usar EXCLUDE em código SQL de produção?

Embora a nova sintaxe seja ótima para agilizar workflows ad hoc, ela não é recomendada para código SQL de produção. O ideal é ser explícito sobre exatamente quais colunas você está selecionando. Listar todos os nomes de coluna melhora a legibilidade e a auditabilidade. Quem lê seu SQL entende na hora quais colunas você está usando de cada tabela. Isso também ajuda a gerar erros mais claros: se uma coluna for removida da tabela, seu SQL vai falhar de imediato — bem melhor do que uma aplicação downstream quebrar de surpresa por causa de uma coluna ausente.

Usar EXCLUDE no Snowflake gera um query plan ou desempenho diferente?

Não. Usar a palavra-chave EXCLUDE para remover algumas colunas não muda o query plan nem o desempenho da consulta em comparação a listar todas as colunas explicitamente. Você mesmo pode validar esse comportamento rodando os dois tipos de consulta em um dataset da sua conta Snowflake e inspecionando o query profile de cada uma.

Como renomear colunas ao executar um SELECT \* no Snowflake?

Antes da nova funcionalidade RENAME, bastava precisar renomear uma única coluna em um SELECT * para ser obrigado a listar todas as outras. Agora dá para selecionar todas as colunas e renomear apenas um subconjunto:

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

Muito melhor do que ter que listar todos os campos só para renomear um ou dois:

-- 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

Assim como no EXCLUDE, também funciona para uma única coluna, com parênteses opcionais:

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

Combinando EXCLUDE e RENAME

Dá para combinar EXCLUDE e RENAME tranquilamente, como no exemplo abaixo:

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

Bem melhor do que o código mostrado no começo do post:

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

Notas

  1. Para você ter uma ideia da demanda, esta pergunta no Stack Overflow, feita há quase 14 anos, tem 1,3 milhão de visualizações e mais de 1.000 upvotes

  2. Valeu, Nate Sooter, por inspirar este exemplo com seu tweet recente!

Ian Whitestone·Cofundador e CEO da SELECT

Ian é cofundador e CEO da SELECT, uma plataforma SaaS de gestão e otimização de custos do Snowflake. Antes de fundar a SELECT, Ian passou 6 anos liderando times full stack de data science e engenharia na Shopify e na Capital One. Na Shopify, Ian liderou o trabalho de otimizar o data warehouse e ampliar a observabilidade de custos.