Curso
Ao escrever consultas SQL, geralmente seguimos uma determinada ordem. (O SQL é conhecido por ser escrito de dentro para fora). No entanto, os mecanismos SQL seguem uma ordem específica de execução ao compilar consultas, que é diferente da ordem típica de escrita. Entender a ordem de execução do SQL é importante para dominar a otimização da consulta, melhorar a precisão e o desempenho da consulta e depurar problemas complexos, como você verá.
Para começar, recomendo que você faça o curso de Introdução ao SQL do DataCamp e o curso de habilidades SQL Fundamentals para aprender os fundamentos do SQL e como extrair dados usando consultas. A folha de dicas básicas de SQL será um guia útil para funções SQL comuns para filtragem e agregação de dados.
O que é a ordem de execução do SQL?
A ordem de execução do SQL refere-se à ordem em que as diferentes cláusulas da consulta são avaliadas. Vale a pena entender isso porque a ordem de execução geralmente é diferente de como escrevemos as consultas SQL. Para dar o exemplo mais simples, você pode pensar que, no caso de SELECT * FROM database
, a cláusula SELECT
é avaliada primeiro, mas, na verdade, a ordem de execução começa com a cláusula FROM
.
Aqui está a ordem de execução do SQL. Na próxima seção, examinaremos as etapas em detalhes.
- DE/JOIN: Especifica as tabelas das quais você deve recuperar dados.
- WHERE: Filtra as linhas que atendem à condição antes do agrupamento.
- GROUP BY: Agrupa linhas que compartilham uma propriedade.
- HAVING: Filtra grupos com base em condições, aplicadas após o agrupamento.
- SELECIONE: Especifica as colunas a serem recuperadas ou calculadas.
- DISTINCT: Remove as linhas duplicadas do conjunto de resultados.
- ORDER BY: Classifica o conjunto de resultados por colunas especificadas.
- LIMIT: Especifica o número máximo de linhas a serem retornadas.
- OFFSET: Especifica quantas linhas você deve ignorar antes de começar a retornar as linhas.
Na consulta a seguir, adicionei comentários para mostrar quais são avaliados primeiro.
-- #6+7 SELECT DISTINCT department_id
-- #1 FROM employees
-- #2 JOIN orders ON customers.customer_id = orders.customer_id
-- #3 WHERE salary > 3000
-- #4 GROUP BY department
-- #5 HAVING AVG(salary) > 5000
-- #8 ORDER BY department
-- #9 LIMIT 10 OFFSET 5
-- #10 OFFSET 5 ROWS FETCH NEXT 10 ROWS ONLY;
Também criei um acróstico que pode ajudar: Para ver as metase os obstáculos do trabalho , pesquiseas oportunidades de aprendizado organizadodo DataCamp.
Estágios da execução de consultas SQL
Embora a maioria das consultas SQL que escrevemos comece com a instrução SELECT
, a ordem lógica de execução começa com a cláusula FROM
. Aqui, escreverei consultas para mostrar a ordem de execução da consulta . No entanto, lembre-se de que essas consultas são incompletas e não serão compiladas.
Cláusula FROM
As consultas SQL iniciam o processo de execução com a cláusula FROM
. Normalmente, esse é o primeiro estágio, pois o banco de dados identifica as fontes/tabelas de dados. Quando várias tabelas estiverem envolvidas, a consulta SQL também avaliará a condição JOIN
para combinar as tabelas especificadas como a fonte de dados.
A consulta incompleta abaixo selecionaria primeiro os dados da tabela customers
usando a cláusula FROM
e a tabela orders
usando a cláusula JOIN
.
FROM customers
JOIN orders ON customers.customer_id = orders.customer_id;
Cláusula WHERE
A cláusula WHERE
é executada após as cláusulas FROM
e JOIN
para filtrar as linhas com base em condições específicas. É importante observar que as colunas definidas com aliases na cláusula SELECT
não podem ser referenciadas diretamente na cláusula WHERE
, pois ela é processada antes da SELECT
.
A consulta abaixo usa a cláusula WHERE
para filtrar registros de funcionários com um bonus
maior que 5000.
FROM employees
JOIN orders ON customers.customer_id = orders.customer_id
WHERE salary * 0.1 > 5000;
Como o bonus
é um alias na declaração SELECT
, se você usá-lo na cláusula WHERE
, ocorrerá um erro. Em vez disso, você deve repetir a expressão completa salary * 0.1
na cláusula WHERE
.
Cláusula GROUP BY
Depois de filtrar as linhas, o SQL executa a cláusula GROUP BY
para agrupar os resultados com base nas colunas especificadas. Essa etapa geralmente é usada com funções de agregação como COUNT()
, SUM()
e AVG()
para realizar alguns cálculos nas colunas especificadas.
A consulta abaixo primeiro filtra os funcionários com um salary
maior que 3,000
, depois os agrupa por department
e calcula o salário médio de cada grupo.
FROM employees
JOIN orders ON customers.customer_id = orders.customer_id
WHERE salary > 3000
GROUP BY department;
Cláusula HAVING
A cláusula HAVING
é semelhante à cláusula WHERE
, mas é usada para filtrar dados agrupados após a operação GROUP BY
. Na consulta abaixo, o SQL agrupa employees
por department
, calcula o salário médio de cada grupo e, em seguida, filtra os grupos em que o salário médio é menor ou igual a 5,000
.
FROM employees
JOIN orders ON customers.customer_id = orders.customer_id
WHERE salary > 3000
GROUP BY department
HAVING AVG(salary) > 5000;
A consulta acima não pode usar a cláusula WHERE
, pois ela não funciona em resultados agregados.
Cláusula SELECT
A cláusula SELECT
é onde o SQL deriva as colunas ou expressões a serem retornadas após a execução das etapas anteriores. Você pode aplicar operações aritméticas, aliasing e funções agregadas na cláusula SELECT
.
A consulta a seguir usa a cláusula SELECT
para recuperar os dados name
e bonus
calculados como salary * 0.1
da tabela employees
.
SELECT department, AVG(salary)
FROM employees
JOIN orders ON customers.customer_id = orders.customer_id
WHERE salary > 3000
GROUP BY department
HAVING AVG(salary) > 5000;
Cláusula DISTINCT
A cláusula DISTINCT
é avaliada após a cláusula SELECT em uma consulta. A cláusula DISTINCT
é importante para remover registros duplicados de uma tabela porque ela retorna linhas exclusivas. A consulta abaixo retorna cada department_id
exclusivo, filtrando as duplicatas.
SELECT DISTINCT department_id
FROM employees
JOIN orders ON customers.customer_id = orders.customer_id
WHERE salary > 3000
GROUP BY department
HAVING AVG(salary) > 5000;
Cláusula ORDER BY
A cláusula ORDER BY
classifica o conjunto de resultados de colunas ou expressões específicas. Diferentemente da cláusula WHERE
, a cláusula ORDER BY
pode usar aliases de coluna definidos na instrução SELECT
.
A consulta abaixo classifica a coluna bonus
em ordem decrescente. Observe que o bonus
foi definido na instrução SELECT
como um alias de uma expressão.
SELECT DISTINCT department_id
FROM employees
JOIN orders ON customers.customer_id = orders.customer_id
WHERE salary > 3000
GROUP BY department
HAVING AVG(salary) > 5000;
ORDER BY bonus DESC;
Cláusula LIMIT/OFFSET
As cláusulas LIMIT
e OFFSET
geralmente são as últimas a serem executadas em uma consulta SQL para restringir o número de linhas a serem retornadas. A cláusula LIMIT
especifica o número máximo de linhas a serem retornadas, e OFFSET
especifica quantas linhas você deve ignorar antes de começar a retornar as linhas.
A consulta abaixo recupera os nomes e salários dos funcionários, classifica-os por salary
em ordem decrescente e limita a saída a 10 resultados, ignorando as primeiras 5 linhas.
SELECT DISTINCT department_id
FROM employees
JOIN orders ON customers.customer_id = orders.customer_id
WHERE salary > 3000
GROUP BY department
HAVING AVG(salary) > 5000
ORDER BY bonus DESC
LIMIT 10 OFFSET 5
-- OFFSET 5 ROWS FETCH NEXT 10 ROWS ONLY; --SQL SERVER / ORACLE
As cláusulas LIMIT
e OFFSET
são compatíveis com os bancos de dados MySQL e PostgreSQL. No SQL Server e no Oracle, você usa OFFSET
, ROWS FETCH
e ROWS ONLY
para restringir o número de linhas a serem retornadas de uma consulta.
Confira nosso tutorial sobre Como usar o SQL OFFSET para saber mais sobre a paginação de dados e o suporte específico do banco de dados para as cláusulas OFFSET
e LIMIT
.
Ordem de execução do SQL versus ordem de execução do SQL. Ordem de escrita
O SQL é uma linguagem declarativa, o que significa que a ordem de execução da consulta é diferente da ordem escrita. Portanto, em vez de especificar como executar uma tarefa, você declara o que deseja e o mecanismo do banco de dados decide a melhor maneira de alcançá-lo. Esse método é diferente das linguagens de programação imperativas, como Python ou Java, em que você escreve explicitamente instruções passo a passo para execução.
Entender a ordem de execução do SQL muda a forma como você pensa sobre a construção de consultas. Por exemplo, imagine que você escreva uma consulta para filtrar linhas com base em um alias que você criou na cláusula SELECT
:
SELECT price * 0.9 AS discounted_price
FROM products
WHERE discounted_price > 100;
À primeira vista, isso parece lógico, mas gera um erro. Por quê? Porque a cláusula WHERE
é avaliada antes da cláusula SELECT
na ordem de execução do SQL. Para corrigir isso, você precisaria usar uma subconsulta ou HAVING
:
SELECT price * 0.9 AS discounted_price
FROM products
HAVING discounted_price > 100;
Para saber mais sobre WHERE
e HAVING
especificamente, leia nosso tutorial: A diferença entre WHERE e HAVING no SQL.
Erros comuns e práticas recomendadas
Embora a ordem de execução da consulta não seja afetada pela ordem de gravação, é fundamental entender o fluxo de execução para evitar erros comuns e melhorar o desempenho da consulta. Os erros a seguir estão diretamente relacionados ao fato de você não entender a ordem de execução do SQL:
Erros comuns
Veja a seguir os erros comuns que podem prejudicar o desempenho da consulta.
-
Uso de aliases de coluna na cláusula WHERE: A cláusula
WHERE
é executada antes da cláusulaSELECT
, portanto, ela gerará um erro se você usar um alias na cláusulaWHERE
. Para evitar esse erro, sempre use a expressão original em vez de um alias na cláusulaWHERE
. -
Uso de aliases de coluna na cláusula WHERE: Como a cláusula
WHERE
é executada antes da cláusulaSELECT
, se você tentar usar um alias emWHERE
, ocorrerá um erro. Entender que o SQL avaliaWHERE
antes da cláusulaSELECT
ensina que você precisa repetir a expressão completa em vez de confiar em um alias. -
Usando HAVING para filtragem de linha em vez de WHERE: A cláusula
HAVING
é executada apósGROUP BY
e foi projetada para filtrar dados agregados. Se você estiver filtrando dados não agregados, isso deve ser feito na cláusula WHERE. Conhecer a diferença na ordem de execução entre WHERE e HAVING ajuda você a determinar onde cada condição deve ser colocada. -
Uso incorreto de agregados no SELECT sem GROUP BY: Como o
GROUP BY
é executado antes doHAVING
ou doSELECT
, se você não agrupar os dados antes de aplicar uma função de agregação, obterá resultados incorretos ou erros. Entender a ordem de execução esclarece por que essas duas cláusulas devem andar juntas. -
Não usar aliases corretamente na cláusula ORDER BY: Diferentemente da cláusula
WHERE
, a cláusulaORDER BY
é avaliada apósSELECT
. Isso permite que você use aliases criados emSELECT
para classificação, ajudando a evitar confusão ao saber quando os aliases estão disponíveis para uso.
Práticas recomendadas
Considere as práticas recomendadas a seguir para garantir que suas consultas sejam executadas conforme o esperado.
-
Filtrar antecipadamente com WHERE: Como a cláusula
WHERE
é executada antes deGROUP BY
eJOIN
, a aplicação de filtros antecipadamente reduz o número de linhas processadas pelas cláusulas subsequentes, melhorando o desempenho da consulta. Ao filtrar os dados não agregados o mais cedo possível, você limita os dados que precisam ser agrupados ou unidos, economizando tempo de processamento. -
Pre-Aggregate Data Before Joins: Sabendo que
FROM
eJOIN
são as primeiras cláusulas executadas, a pré-agregação de dados usando subconsultas ou expressões de tabela comum (CTEs) permite que você reduza o conjunto de dados antes do processo de união. Isso garante que menos linhas sejam processadas durante a união. -
Otimizar ORDER BY com índices: Como a cláusula
ORDER BY
é uma das últimas etapas executadas, garantir que as colunas classificadas sejam indexadas acelerará o desempenho da consulta, ajudando o banco de dados a lidar com as operações de classificação de forma mais eficiente. -
Evite o SELECT * em consultas de produção: A cláusula
SELECT
é executada após a filtragem, o agrupamento e a agregação, portanto, especificar somente as colunas necessárias minimiza a quantidade de dados recuperados, reduzindo a sobrecarga desnecessária.
Conclusão
Entender a ordem de execução do SQL é importante para que você escreva consultas eficientes, precisas e otimizadas. Discutimos a ordem lógica da execução de consultas no SQL e a comparamos com a ordem escrita. Recomendo que você pratique a criação de diferentes consultas para entender melhor a ordem lógica de execução. O domínio desse conceito melhorará muito sua capacidade de solucionar problemas e otimizar consultas SQL.
Se você deseja aprimorar suas habilidades em SQL, recomendo que experimente o curso de carreira Associate Data Analyst in SQL da DataCamp para se tornar um analista de dados proficiente. O curso Reporting in SQL também ajudará você a se tornar proficiente na criação de relatórios e painéis complexos para a apresentação eficaz de dados. Por fim, você deve obter a Certificação SQL Associate para demonstrar seu domínio no uso do SQL para resolver problemas de negócios e se destacar entre outros profissionais.
Torne-se um engenheiro de dados
Perguntas frequentes sobre a ordem de execução do SQL
Como a execução do SQL difere da ordem escrita?
A ordem de execução do SQL geralmente começa com a cláusula FROM
, seguida de cláusulas como WHERE
e GROUP BY
, enquanto a ordem de escrita começa com a instrução SELECT
.
Como o JOIN se encaixa na ordem de execução?
As operações do JOIN
são executadas como parte da cláusula FROM
.
Posso usar aliases de coluna na cláusula WHERE?
Não, os aliases de coluna são definidos na cláusula SELECT
, executada após a cláusula WHERE
.
Qual é a diferença entre WHERE e HAVING?
WHERE
filtra as linhas antes do agrupamento, enquanto HAVING
filtra após GROUP BY
e trabalha com dados agregados.
A ordem de execução do SQL afeta o desempenho da consulta?
Sim, compreender a ordem de execução permite que você otimize as consultas aplicando filtros antecipadamente e reduzindo operações desnecessárias.