Ir para o conteúdo principal

SQL Fica Mais Fácil: Anunciando Nova Sintaxe Pipe

Torne o SQL mais simples e forte expressando todas as transformações em ordem

SQL Gets Easier: Announcing New Pipe Syntax

Published: April 30, 2025

Engenharia9 min de leitura

Summary

  • SQL é bem-sucedido porque a linguagem declara quais dados devem sair de cada consulta sem especificar exatamente como o motor deve executá-la.
  • No entanto, SQL pode ser confuso para novos usuários aprenderem e para usuários existentes manterem, especialmente na presença de muitas subconsultas aninhadas.
  • Aqui anunciamos uma nova sintaxe para ajudar com isso, permitindo que os usuários componham a lógica SQL como uma sequência de cláusulas independentes organizadas em qualquer ordem, muito parecido com DataFrames.

O SQL tem sido a língua franca para análise de dados estruturados por várias décadas, e temos feito muito trabalho nos últimos anos para suportar o ANSI SQL e as várias extensões para tornar o SQL mais agradável de usar no Databricks. Hoje, estamos animados para anunciar a sintaxe de pipe SQL, a maior extensão que fizemos nos últimos anos para tornar o SQL dramaticamente mais fácil de escrever e entender, de uma maneira totalmente compatível com versões anteriores.

Um dos principais desafios no próprio SQL até agora reside na ordenação da "lógica". Ao escrever uma consulta, muitos autores pensam em termos dos seguintes passos lógicos: identificar a lista de tabelas para consultar, juntá-las, filtrar as linhas indesejadas e, finalmente, agregar. Essa ordenação lógica pode ser expressa da seguinte maneira:

A consulta SQL para essas etapas seria assim:

Em vez de escrever as etapas em ordem (1, 2, 3) devemos escrevê-las na ordem (3, 2, 1). Isso é confuso e o problema só se agrava à medida que adicionamos mais lógica e etapas a cada consulta.

DataFrames e as pessoas que os amam

Em contraste, vamos pensar sobre DataFrames. Uma grande fonte da popularidade original do Apache Spark entre os cientistas de dados é a poderosa capacidade de suas APIs DataFrame em Scala e Python. Os programas podem aplicar isso para expressar sua lógica em uma ordem natural de etapas. Partindo da tabela de origem, os usuários podem encadear operações independentes e compostas uma após a outra, facilitando a construção de transformações de dados complexas em uma sequência clara e intuitiva.

Este design promove a legibilidade e simplifica a depuração, mantendo a flexibilidade. É uma das principais razões pelas quais a Databricks conquistou seu enorme crescimento na indústria até agora no espaço de gerenciamento de dados, e esse ímpeto só continua a aumentar hoje.

Veja como essa mesma lógica se parece em DataFrames PySpark:

Essa abordagem suporta a iteração flexível de ideias. Sabemos que os dados de origem existem em algum arquivo, então podemos começar imediatamente criando um DataFrame que representa esses dados como uma relação. Depois de pensar um pouco, percebemos que queremos filtrar as linhas pela coluna de string. OK, então podemos adicionar um passo .filter ao final do DataFrame anterior. Ah, e queremos calcular uma projeção no final, então adicionamos isso ao final da sequência.

Muitos desses usuários desejam que o SQL se comporte de maneira mais semelhante a linguagens de dados modernas como esta. Historicamente, isso não era possível, e os usuários tinham que escolher um modo de pensar ou outro.

Apresentando a nova sintaxe SQL pipe!

Avançando para hoje: agora é possível ter o melhor dos dois mundos! A sintaxe Pipe torna o SQL mais fácil de escrever, ler e estender posteriormente, e nos liberta dessa confusão, permitindo-nos simplesmente usar as mesmas etapas na ordem em que pensamos nelas.

Na conferência VLDB 2024, o Google publicou um artigo industrial propondo isso como um novo padrão. Engenheiros de processamento de consultas implementaram essa funcionalidade e a habilitaram por padrão no Apache Spark 4.0 (documentação) e Databricks Runtime 16.2 (documentação) em diante. É compatível com a sintaxe SQL regular: os usuários podem escrever consultas inteiras usando esta sintaxe, apenas certas subconsultas, ou qualquer combinação útil.

O artigo industrial fornece a consulta 13 do benchmark TPC-H como o primeiro exemplo:

Usando a sintaxe pipe para expressar a mesma lógica, aplicamos operadores em uma sequência do início ao fim com qualquer ordenação arbitrária:

E como funcionam as agregações?

Com SQL regular, quando queremos coletar linhas em grupos com base em valores de coluna ou expressão, adicionamos uma cláusula GROUP BY ao final da consulta SQL em construção. As agregações a serem realizadas permanecem presas lá no início da consulta na lista SELECT e cada expressão agora deve ser:

  • Uma chave de agrupamento, caso em que a cláusula GROUP BY deve conter uma cópia da expressão (ou uma referência de alias ou ordinal).
  • Uma função agregada como SUM, COUNT, MIN, ou MAX, aceitando uma expressão baseada em colunas da tabela de entrada como SUM(A + B). Também podemos calcular projeções no resultado, como SUM(A) + 1.

Qualquer item SELECT que não atenda a uma dessas categorias gerará algum erro como “a expressão X apareceu na lista SELECT, mas não foi agrupada ou agregada.”

As regras da cláusula WHERE também mudam:

  • Se aparecer antes da cláusula GROUP BY, então filtramos as linhas de acordo com os critérios especificados antes de agregá-las.
  • Caso contrário, a consulta não é válida e obtemos um erro estranho. O usuário deve, em vez disso, escrever uma cláusula HAVING com a mesma condição de filtragem e ela deve aparecer apenas após a cláusula GROUP BY, mas não antes dela.
  • A cláusula QUALIFY também serve como outro exemplo da necessidade de entender e usar uma sintaxe separada para realizar a filtragem, dependendo do contexto.

A sintaxe Pipe resolve isso separando cada operação de agregação (com possível agrupamento) em uma etapa dedicada que pode ser aplicada a qualquer momento. Apenas expressões com funções agregadas podem aparecer dentro desta etapa, e funções agregadas não podem aparecer dentro das etapas |> SELECT. Se o autor do SQL esquecer qualquer um desses invariantes, as mensagens de erro resultantes são muito claras e fáceis de entender.

Também não há mais necessidade de repetir as expressões de agrupamento, já que podemos simplesmente escrevê-las em uma única cláusula GROUP BY.

Vamos olhar para o exemplo anterior com uma agregação anexada ao final, que retorna uma tabela de resultados com duas colunas L, M:

Diversão com subconsultas

O SQL regular geralmente exige que as cláusulas apareçam em uma ordem específica, sem repetição. Se quisermos aplicar mais operações no resultado de uma consulta SQL, a maneira de fazer isso é usar uma subconsulta de tabela onde envolvemos a consulta original entre parênteses e a usamos na cláusula FROM de uma consulta envolvente. A consulta no início deste post mostra um exemplo simples disso.

Note que essa aninhamento pode ocorrer um número arbitrário de vezes. Por exemplo, aqui está a consulta TPC-DS 23:

Está ficando confuso e mais difícil de ler com todos os níveis de parênteses e indentação!

Por outro lado, com a sintaxe SQL pipe, não há necessidade de subconsultas de tabela. Como os operadores de pipe podem aparecer em qualquer ordem, podemos simplesmente adicionar novos ao final a qualquer momento, e todas as etapas ainda funcionam da mesma maneira.

Comece facilmente com a compatibilidade retroativa

A sintaxe pipe reestrutura como os autores escrevem, leem e estendem o SQL. Pode parecer um desafio mudar do pensamento de como o SQL regular funciona para esse novo paradigma. Você pode até ter um grande corpo de consultas SQL existentes escritas anteriormente que você é responsável por manter e possivelmente estender posteriormente. Como podemos fazer isso funcionar com duas sintaxes SQL?

Felizmente, isso não é um problema com nossa nova sintaxe SQL. É totalmente interoperável com o SQL regular, onde qualquer consulta (ou subconsulta de tabela) pode aparecer usando qualquer sintaxe. Podemos começar a escrever novas consultas usando a sintaxe SQL pipe e manter as anteriores, se necessário. Podemos até começar a substituir subconsultas de tabela de nossas consultas anteriores pela nova sintaxe e manter tudo o resto igual, como atualizar apenas parte do TPC-H Q13 desde o início deste post:

Como os operadores SQL pipe podem seguir qualquer consulta válida, também é possível começar a anexá-los a consultas SQL regulares existentes. Por exemplo:

Experimente hoje!

A sintaxe SQL pipe está pronta para você testar na versão 16.2 e posteriores do Databricks Runtime. Ou baixe o Apache Spark 4.0 e experimente no mundo open source. A sintaxe está de acordo com o Pipe Syntax in SQL artigo industrial, então a nova sintaxe será portável com o Google BigQuery, bem como o projeto open source ZetaSQL.

Esta sintaxe também está começando a gerar burburinho na comunidade e aparecer em outros lugares, aumentando a portabilidade agora e ao longo do tempo.

Dê uma chance e experimente os benefícios de tornar as consultas SQL mais simples de escrever para usuários novos e experientes, e facilite a legibilidade e extensibilidade futuras, reduzindo a incidência de subconsultas complexas em favor de operadores claros e compostos.

 

(This blog post has been translated using AI-powered tools) Original Post

Nunca perca uma postagem da Databricks

Inscreva-se nas categorias de seu interesse e receba as últimas postagens na sua caixa de entrada