Consultas SQL, NULL e agregação

Junções, quantificação, grupos e consultas analíticas, com resultados calculados sobre dados pequenos.

TLDR

Perguntar sobre esta página

ChatGPTClaudePerplexityGrokGeminiCopiar e abrirDeepSeekCopiar e abrir

Linhas, grupos e repetidos

Fixa primeiro o significado de uma linha do resultado. A ordem lógica útil é FROM/JOIN → WHERE → GROUP BY → HAVING → SELECT → DISTINCT → ORDER BY → LIMIT; o plano físico pode executar de outra forma.

  • WHERE filtra linhas; HAVING filtra grupos.
  • SQL conserva repetidos. DISTINCT elimina linhas iguais da projeção, mas não corrige uma junção errada.
  • UNION elimina repetidos; UNION ALL conserva-os.
  • Seleção e projeção da álgebra relacional correspondem aproximadamente a filtros e escolha de colunas. A projeção clássica elimina repetidos e não usa a semântica de NULL de SQL.

NULL e agregação

NULL significa informação ausente. x = NULL dá desconhecido; usa IS NULL. WHERE só conserva verdadeiro, enquanto CHECK também aceita desconhecido.

ExpressãoResultado
TRUE AND NULLDesconhecido
FALSE AND NULLFalso
TRUE OR NULLVerdadeiro
FALSE OR NULL, NOT NULLDesconhecido

COUNT(*) conta linhas; COUNT(coluna) conta valores não nulos. SUM, AVG, MIN e MAX ignoram NULL; SUM sem valores dá NULL. COALESCE(SUM(preco),0) escolhe interpretar a ausência como zero.

Conservar linhas sem correspondência

Aqui S1 tem um pago e um cancelado; S2 não tem bilhetes; S3 só tem um cancelado. As CTEs são dados mínimos para isolar a consulta.

Contar pagos sem perder sessões
WITH sessoes(id) AS (VALUES (1),(2),(3)),
bilhetes(id,sessao_id,estado) AS (
VALUES (10,1,'pago'),(11,1,'cancelado'),(12,3,'cancelado')
)
SELECT s.id, COUNT(b.id) AS pagos
FROM sessoes s
LEFT JOIN bilhetes b
ON b.sessao_id = s.id AND b.estado = 'pago'
GROUP BY s.id ORDER BY s.id;
Resultado

Executa a consulta para ver as tabelas.

Resultado: (1,1), (2,0), (3,0). O filtro no ON escolhe correspondências; LEFT JOIN conserva as outras sessões. Mover o filtro de estado para WHERE elimina S2 e S3. COUNT(*) contaria a linha exterior como um.

Existência e quantificação

  • EXISTS testa existência de linhas. NOT EXISTS correlacionado exprime ausência de correspondências.
  • 2 NOT IN (1,NULL) é desconhecido. Uma subconsulta nullable pode provocar esta armadilha; NOT EXISTS com a correlação correta evita-a.
  • “Comprou em todas as sessões” traduz-se em “não existe sessão para a qual não existe compra”. Sem sessões, aceita por vacuidade; acrescenta EXISTS se exigires alguma sessão.

Janelas e resultados intermédios

SUM(preco) OVER (PARTITION BY sessao_id) mantém cada venda e acrescenta o total da sessão: duas vendas de 8 e 12 continuam em duas linhas, ambas com total 20. GROUP BY reduz a uma linha por grupo. ROW_NUMBER numera segundo a ordenação da janela.

Uma CTE WITH nome AS (...) nomeia um resultado intermédio; não promete materialização nem melhoria de desempenho.

Quantificação e consultas completas.

Agregação e duas relações 1:N

Dois bilhetes pagos de 20 euros e três etiquetas da mesma sessão produzem seis pares numa junção: SUM dá 120, embora a receita seja 40. SUM DISTINCT dá 20 e também está errado, pois os bilhetes têm preços iguais.

Agrega bilhetes e etiquetas separadamente por sessão, depois junta os resultados com no máximo uma linha por sessão. LEFT JOIN conserva sessões sem grupo; COALESCE só atribui zero quando esse é o significado pretendido. EXISTS pode testar etiquetas sem multiplicar vendas.

Multiplicação e consulta completa.

À tua maneira

Aparência

Modo de cor
Tema
Cor de destaque

Leitura

Fonte de leitura

Álgebra, lógica e uma ideia de cada vez.

Código

Fonte do código

Navegação

Cursor de leitura, sem edição. h, j, k, l movem; / pesquisa nesta página. v seleciona caracteres; V seleciona linhas; y copia. Tab permite destacar ou comentar. Espaço ou Enter abre blocos recolhíveis. Nos cartões, h, j, k, l mudam o foco.

CSS personalizado

Ativa uma sugestão ou guarda o teu CSS. Só muda este navegador.

Usa --page, --text e --accent para acompanhar o tema.

Seletores e recuperação

.site-header, .prose, .course-card, [data-reading-history], [data-playground] e .page-actions.

Abre a aparência com a tecla vírgula ou no rodapé. Se o CSS esconder os controlos, abre esta página sem CSS personalizado.

Pesquisar

Escreve para pesquisar em todo o site.

para escolher · Enter para abrir · Esc para fechar

Copiar fórmula

A cópia automática não está disponível. Copia o LaTeX abaixo.

Pesquisar nesta página

Enter procura · n / N repetem · Esc cancela. Ctrl / Cmd K pesquisa todo o site.

Atalhos de teclado

Clica numa tecla para a mudar. Esc cancela. Backspace desativa.

PesquisarCtrl / Cmd K

Os atalhos não interferem enquanto escreves. Tab e Enter funcionam sempre.