SQL Avancado para Entrevistas de Analista de Dados: Subqueries, Pivots e Otimizacao de Consultas 2026
Guia completo de SQL avancado para entrevistas de analista de dados em 2026. Subqueries correlacionadas, tabelas pivot com agregacao condicional, planos EXPLAIN ANALYZE e estrategias de indexacao no PostgreSQL 17 com exemplos praticos.

Processos seletivos para analista de dados em 2026 exigem dominio de SQL muito alem do basico. Recrutadores de empresas como Nubank, iFood, Mercado Livre e consultorias de dados avaliam candidatos em tres pilares tecnicos: subqueries correlacionadas, transformacoes pivot e otimizacao de consultas. Essas habilidades separam o profissional que apenas extrai dados daquele capaz de construir pipelines analiticos eficientes em bases com milhoes de registros. Este artigo apresenta os padroes exatos cobrados em avaliacoes tecnicas, com queries prontas para execucao no PostgreSQL 17.
Entrevistas de SQL para vagas de analista de dados em 2026 focam em tres competencias: capacidade de decompor logica complexa em subqueries legiveis ou CTEs, habilidade de transformar dados tabulares em relatorios pivotados via agregacao condicional, e conhecimento pratico de performance atraves de planos EXPLAIN e indexacao. A maioria dos candidatos reprova na parte de otimizacao — dominar esse tema garante vantagem competitiva real.
Subqueries Correlacionadas vs. Subqueries Regulares
A diferenca entre uma subquery correlacionada e uma subquery regular e um dos temas mais recorrentes em entrevistas tecnicas. Uma subquery regular executa uma unica vez e produz um resultado fixo. Ja a subquery correlacionada faz referencia a uma coluna da consulta externa, forcando o banco de dados a reexecuta-la para cada linha do resultado principal. Saber quando usar cada abordagem — e quando substituir ambas por um JOIN — e exatamente o que entrevistadores buscam avaliar.
A subquery regular e ideal para comparacoes contra valores escalares. No exemplo abaixo, a media e calculada uma unica vez, e todas as linhas sao filtradas contra esse valor.
-- regular_subquery_threshold.sql
-- Find all orders above the average order value
SELECT
order_id,
customer_id,
total_amount
FROM orders
WHERE total_amount > (
-- Executes once, returns a single scalar value
SELECT AVG(total_amount)
FROM orders
);Quando a comparacao depende do contexto individual de cada linha, a subquery correlacionada se torna necessaria. O exemplo classico de entrevista e: "Encontre os funcionarios que ganham acima da media salarial do proprio departamento."
-- correlated_subquery_department.sql
-- Employees earning above their department average
SELECT
e.employee_id,
e.name,
e.department,
e.salary
FROM employees e
WHERE e.salary > (
-- Re-evaluated for each employee's department
SELECT AVG(e2.salary)
FROM employees e2
WHERE e2.department = e.department
);O problema dessa abordagem e a performance. O calculo de AVG e repetido para cada funcionario, gerando custo proporcional ao numero de linhas. Em tabelas corporativas com centenas de milhares de registros, esse comportamento torna a consulta impraticavel. A solucao profissional utiliza uma CTE para calcular todas as medias departamentais em uma unica passagem pelo dado.
-- optimized_with_cte.sql
-- Same result, single pass over the data
WITH dept_avg AS (
SELECT
department,
AVG(salary) AS avg_salary
FROM employees
GROUP BY department
)
SELECT
e.employee_id,
e.name,
e.department,
e.salary
FROM employees e
JOIN dept_avg d ON e.department = d.department
WHERE e.salary > d.avg_salary;O candidato que apresenta a versao correlacionada, reconhece o problema de performance e refatora para CTE demonstra o nivel de maturidade tecnica que diferencia um profissional pleno de um senior. Entrevistadores valorizam especialmente essa capacidade de transitar entre abordagens e justificar a escolha.
Padroes de Subquery Comuns em Entrevistas para Analista de Dados
Tres padroes de subquery aparecem com frequencia elevada em processos seletivos: EXISTS para verificacoes de existencia, subqueries escalares na clausula SELECT e tabelas derivadas na clausula FROM.
EXISTS vs. IN — O operador EXISTS interrompe a busca assim que encontra a primeira correspondencia, tornando-o significativamente mais rapido que IN em conjuntos de dados volumosos. O IN, por sua vez, materializa todo o resultado da subquery em memoria antes de iniciar a comparacao.
-- exists_vs_in.sql
-- Customers who placed at least one order in 2026 (EXISTS — preferred)
SELECT c.customer_id, c.name
FROM customers c
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.customer_id = c.customer_id
AND o.order_date >= '2026-01-01'
);
-- Equivalent with IN (slower on large datasets)
SELECT customer_id, name
FROM customers
WHERE customer_id IN (
SELECT customer_id
FROM orders
WHERE order_date >= '2026-01-01'
);Na pratica do mercado brasileiro, onde bases de e-commerce e fintech frequentemente ultrapassam dezenas de milhoes de transacoes, a escolha entre EXISTS e IN pode representar a diferenca entre uma query que retorna em segundos e outra que consome minutos.
Subquery escalar no SELECT — Permite adicionar uma coluna calculada ao resultado sem a complexidade de um JOIN dedicado.
-- scalar_subquery_select.sql
-- Each product with its category's total revenue
SELECT
p.product_id,
p.product_name,
p.category,
(
SELECT SUM(oi.quantity * oi.unit_price)
FROM order_items oi
JOIN products p2 ON oi.product_id = p2.product_id
WHERE p2.category = p.category
) AS category_total_revenue
FROM products p;Esse padrao funciona bem para enriquecer o resultado com uma ou duas colunas adicionais. Quando ha necessidade de multiplas colunas calculadas, uma CTE com JOIN oferece melhor legibilidade e, na maioria dos casos, performance superior.
Pronto para mandar bem nas entrevistas de Data Analytics?
Pratique com nossos simuladores interativos, flashcards e testes tecnicos.
Consultas Pivot com Agregacao Condicional
Consultas pivot sao uma das tecnicas mais cobradas em entrevistas para analistas de dados. O objetivo e transformar dados armazenados em formato de linhas em colunas — por exemplo, converter meses registrados como valores em linhas para colunas individuais como jan_revenue, feb_revenue. Embora alguns SGBDs ofereçam sintaxe PIVOT nativa, a abordagem universal e portavel utiliza expressoes CASE dentro de funcoes de agregacao. Essa e a versao esperada em qualquer entrevista tecnica.
-- pivot_monthly_revenue.sql
-- Monthly revenue pivot: one row per product, one column per month
SELECT
product_id,
product_name,
SUM(CASE WHEN EXTRACT(MONTH FROM order_date) = 1
THEN quantity * unit_price ELSE 0 END) AS jan_revenue,
SUM(CASE WHEN EXTRACT(MONTH FROM order_date) = 2
THEN quantity * unit_price ELSE 0 END) AS feb_revenue,
SUM(CASE WHEN EXTRACT(MONTH FROM order_date) = 3
THEN quantity * unit_price ELSE 0 END) AS mar_revenue,
SUM(CASE WHEN EXTRACT(MONTH FROM order_date) = 4
THEN quantity * unit_price ELSE 0 END) AS apr_revenue,
-- Repeat for remaining months
SUM(quantity * unit_price) AS total_revenue
FROM order_items oi
JOIN orders o ON oi.order_id = o.order_id
JOIN products p ON oi.product_id = p.product_id
WHERE o.order_date >= '2026-01-01'
GROUP BY product_id, product_name
ORDER BY total_revenue DESC;A tecnica de agregacao condicional nao se limita a datas. O mesmo principio permite criar pivots multidimensionais para qualquer campo categorico, como tipos de dispositivo, canais de aquisicao ou regioes geograficas.
-- pivot_user_activity.sql
-- User activity: sessions by day of week and device type
SELECT
user_id,
COUNT(CASE WHEN device_type = 'mobile' THEN 1 END) AS mobile_sessions,
COUNT(CASE WHEN device_type = 'desktop' THEN 1 END) AS desktop_sessions,
COUNT(CASE WHEN device_type = 'tablet' THEN 1 END) AS tablet_sessions,
ROUND(
COUNT(CASE WHEN device_type = 'mobile' THEN 1 END) * 100.0 / COUNT(*),
1
) AS mobile_pct
FROM user_sessions
WHERE session_date >= CURRENT_DATE - INTERVAL '30 days'
GROUP BY user_id
HAVING COUNT(*) >= 5 -- Only users with meaningful activity
ORDER BY mobile_pct DESC;A clausula HAVING filtra usuarios com atividade minima significativa, evitando distorcoes estatisticas causadas por usuarios com poucas sessoes. Esse tipo de refinamento e exatamente o que diferencia uma resposta aceitavel de uma resposta exemplar em entrevista.
Pivot Dinamico com CROSSTAB no PostgreSQL
Quando as categorias do pivot nao sao conhecidas antecipadamente — por exemplo, quando novos produtos sao adicionados ao catalogo periodicamente — a funcao CROSSTAB da extensao tablefunc do PostgreSQL oferece uma solucao elegante.
-- crosstab_dynamic_pivot.sql
-- Enable the extension (once per database)
CREATE EXTENSION IF NOT EXISTS tablefunc;
-- Revenue by product and quarter using CROSSTAB
SELECT *
FROM crosstab(
$$
SELECT
product_name,
'Q' || EXTRACT(QUARTER FROM order_date)::TEXT AS quarter,
SUM(quantity * unit_price) AS revenue
FROM order_items oi
JOIN orders o ON oi.order_id = o.order_id
JOIN products p ON oi.product_id = p.product_id
WHERE EXTRACT(YEAR FROM o.order_date) = 2026
GROUP BY product_name, quarter
ORDER BY product_name, quarter
$$,
$$ VALUES ('Q1'), ('Q2'), ('Q3'), ('Q4') $$
) AS pivot_table(
product_name TEXT,
q1_revenue NUMERIC,
q2_revenue NUMERIC,
q3_revenue NUMERIC,
q4_revenue NUMERIC
);O CROSSTAB recebe duas consultas: a primeira gera os dados no formato linha-coluna-valor, e a segunda define as categorias das colunas. Essa abordagem e especialmente util em dashboards operacionais e relatorios gerenciais que precisam se adaptar automaticamente a novos periodos ou categorias.
Otimizacao de Consultas SQL: Planos EXPLAIN e Diagnostico de Gargalos
Perguntas sobre otimizacao de consultas sao o divisor de aguas em entrevistas tecnicas. Um analista de dados que trabalha com bases de producao — cenario rotineiro em fintechs, marketplaces e startups de dados no Brasil — precisa saber diagnosticar queries lentas. O comando EXPLAIN ANALYZE e a ferramenta primaria para entender como o planejador do PostgreSQL executa uma consulta e onde estao os gargalos de performance.
-- explain_analyze_example.sql
-- Analyze a slow query to identify bottlenecks
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT
c.customer_id,
c.name,
COUNT(o.order_id) AS order_count,
SUM(o.total_amount) AS lifetime_value
FROM customers c
JOIN orders o ON c.customer_id = o.customer_id
WHERE o.order_date >= '2025-01-01'
GROUP BY c.customer_id, c.name
HAVING SUM(o.total_amount) > 1000
ORDER BY lifetime_value DESC;A saida do EXPLAIN ANALYZE contém informacoes criticas que todo candidato deve saber interpretar. Seq Scan indica varredura sequencial — geralmente sinal de indice ausente em tabelas grandes. Index Scan confirma o uso de um indice. O tipo de join (Nested Loop, Hash Join ou Merge Join) revela a estrategia escolhida pelo planejador. A discrepancia entre linhas estimadas e linhas reais aponta para estatisticas desatualizadas, corrigiveis com o comando ANALYZE na tabela. A proporcao entre shared hits e shared reads nos buffers indica a eficiencia do cache do PostgreSQL — quanto maior a taxa de hits, menos operacoes de disco sao necessarias.
Saber explicar esses elementos de forma articulada durante uma entrevista demonstra capacidade de resolver problemas de performance em ambientes reais, nao apenas de escrever queries corretas.
Estrategias de Indexacao para Performance SQL
A indexacao e o mecanismo mais direto para melhorar a performance de consultas, e entrevistadores esperam que candidatos conhecam nao apenas indices simples, mas tambem indices compostos, parciais e covering indexes.
Um indice simples acelera filtros sobre uma unica coluna. Um indice composto cobre multiplas colunas, e a ordem importa: o PostgreSQL utiliza o indice seguindo a regra do prefixo mais a esquerda. Queries que filtram apenas pela segunda coluna do indice nao se beneficiam dele.
-- indexing_strategies.sql
-- Index on order_date: filters a small percentage of rows
CREATE INDEX idx_orders_date ON orders (order_date);
-- Composite index for queries filtering on both columns
CREATE INDEX idx_orders_customer_date
ON orders (customer_id, order_date);
-- Covering index: includes columns needed in SELECT
-- Enables Index Only Scan (no table access)
CREATE INDEX idx_orders_covering
ON orders (customer_id, order_date)
INCLUDE (total_amount, status);O covering index com a clausula INCLUDE adiciona colunas extras as folhas do indice sem incorpora-las a arvore B-tree. Isso permite index-only scans — consultas respondidas inteiramente pelo indice, sem acessar a tabela principal. Em cenarios de leitura intensiva, como dashboards analiticos, o ganho de performance pode ser de ordens de magnitude.
Indices parciais restringem a cobertura do indice a um subconjunto de linhas, reduzindo tanto o tamanho quanto o custo de manutencao.
-- partial_index.sql
-- Only index active orders (smaller, faster index)
CREATE INDEX idx_orders_active
ON orders (customer_id, order_date)
WHERE status = 'active';
-- Only index recent data for dashboard queries
CREATE INDEX idx_orders_recent
ON orders (order_date)
WHERE order_date >= '2026-01-01';O indice idx_orders_active cobre apenas pedidos com status ativo. Se a tabela de pedidos contém 10 milhoes de registros, mas apenas 500 mil estao ativos, o indice parcial sera uma fracao do tamanho de um indice completo. O idx_orders_recent segue a mesma logica para dados temporais — ideal para relatorios operacionais que raramente consultam historico.
Indexar todas as colunas de uma tabela nao e uma estrategia valida. Cada indice adicional impoe custo nas operacoes de escrita (INSERT, UPDATE, DELETE). Tabelas com mais de 10 indices em workloads de escrita intensiva sofrem degradacao perceptivel. Tambem e importante evitar indexar colunas de baixa cardinalidade isoladamente (como campos booleanos), a menos que facam parte de um indice composto ou parcial.
Anti-Padroes de Consulta que Comprometem a Performance
Alem de construir queries eficientes, entrevistadores avaliam se o candidato reconhece padroes de escrita SQL que neutralizam as otimizacoes do banco de dados. Dois anti-padroes merecem atencao especial por sua frequencia em provas tecnicas.
Aplicar funcoes sobre colunas indexadas impede o otimizador de utilizar o indice. No exemplo abaixo, a funcao EXTRACT transforma o valor armazenado antes da comparacao, tornando o indice inutilizavel.
-- anti_patterns.sql
-- BAD: function on indexed column disables the index
SELECT * FROM orders
WHERE EXTRACT(YEAR FROM order_date) = 2026;
-- GOOD: range comparison uses the index
SELECT * FROM orders
WHERE order_date >= '2026-01-01'
AND order_date < '2027-01-01';A reescrita como comparacao de intervalo preserva a capacidade do planejador de usar o indice sobre order_date. Esse ajuste aparentemente simples pode reduzir o tempo de execucao de minutos para milissegundos em tabelas volumosas.
O segundo anti-padrao envolve o operador NOT IN na presenca de valores NULL. Quando qualquer valor retornado pela subquery e NULL, a logica ternaria do SQL faz com que NOT IN retorne um conjunto vazio — sem gerar erro algum. A consulta executa normalmente, mas o resultado esta incorreto.
-- not_in_null_trap.sql
-- BAD: returns empty if any customer_id is NULL in subquery
SELECT * FROM customers
WHERE customer_id NOT IN (
SELECT customer_id FROM orders
);
-- GOOD: NOT EXISTS handles NULLs correctly
SELECT * FROM customers c
WHERE NOT EXISTS (
SELECT 1 FROM orders o
WHERE o.customer_id = c.customer_id
);A armadilha do NOT IN com NULL e especialmente perigosa porque nao gera erro de execucao. O candidato que identifica esse problema em entrevista demonstra o tipo de atencao a detalhes que empresas procuram para posicoes que envolvem tomada de decisao baseada em dados.
Para desenvolver fluencia em subqueries, CTEs e otimizacao SQL, o caminho mais eficiente e trabalhar com problemas que simulam situacoes reais de entrevista. Combinar a pratica de refatoracao de subqueries com a analise de planos EXPLAIN constroi a intuicao diagnostica que recrutadores buscam ativamente em candidatos.
Pronto para mandar bem nas entrevistas de Data Analytics?
Pratique com nossos simuladores interativos, flashcards e testes tecnicos.
Conclusao
Dominar SQL avancado e o fator que mais diferencia candidatos em processos seletivos para analista de dados em 2026. Os pontos essenciais abordados neste guia:
- Subqueries correlacionadas reexecutam para cada linha do resultado externo — refatora-las para CTEs ou window functions melhora drasticamente a performance em volumes grandes
- EXISTS supera IN em verificacoes de existencia, especialmente quando a subquery retorna muitas linhas ou contém valores NULL
- Agregacao condicional com CASE e a tecnica de pivotagem portavel e universal — domina-la antes de aprender sintaxes PIVOT especificas de cada banco e fundamental
- EXPLAIN ANALYZE revela o plano de execucao real da query; o foco deve estar em Seq Scans, precisao das estimativas de linhas e estrategia de join escolhida
- A ordem das colunas em indices compostos precisa corresponder aos padroes de filtro das consultas — a regra do prefixo mais a esquerda se aplica sempre
- Indices parciais e covering indexes reduzem operacoes de I/O para padroes de consulta especificos sem a sobrecarga de indices sobre a tabela inteira
- Funcoes sobre colunas indexadas, NOT IN com NULLs e SELECT * em queries de producao sao anti-padroes que devem ser evitados sistematicamente
Comece a praticar!
Teste seus conhecimentos com nossos simuladores de entrevista e testes tecnicos.
Tags
Compartilhar
Artigos relacionados

SQL para Analistas de Dados: Window Functions, CTEs e Consultas Avancadas
Guia completo de SQL avancado com window functions, CTEs e padroes de consulta analitica. Tecnicas essenciais para entrevistas de analise de dados e projetos reais.

As 25 principais perguntas de entrevista em Data Analytics em 2026
As 25 perguntas mais frequentes em entrevistas de data analytics em 2026: SQL, Python, Power BI, estatística e perguntas comportamentais com respostas detalhadas e exemplos de código.

Pandas 3.0 em 2026: novas APIs, mudanças incompatíveis e perguntas de entrevista
Pandas 3.0 traz Copy-on-Write por padrão, um dtype string baseado em PyArrow e o novo construtor de expressões pd.col(). Este mergulho profundo cobre as mudanças principais, padrões de migração e perguntas de entrevista que todo data engineer precisa dominar.