CTEs e consultas recursivas

Resultados intermédios, parte inicial, passo recursivo, hierarquias e terminação.

TLDR

Perguntar sobre esta página

ChatGPTClaudePerplexityGrokGeminiCopiar e abrirDeepSeekCopiar e abrir

Nomear resultados intermédios

WITH dá nome a um resultado dentro de uma instrução; o nome morre no fim dela. Não promete materialização nem desempenho: serve para exprimir cada nível de agregação.

Para totais por cliente: primeiro totais por encomenda, depois por cliente. Juntar antes de agregar multiplica linhas e duplica valores.

  • Contagens de níveis diferentes (freguesias por município, municípios por distrito) pedem CTEs separadas: cada uma com a sua chave.
  • Máximos por grupo correlacionam o MAX pelo grupo e conservam empates; LIMIT 1 global escolhe uma linha para todos.
  • Ao reunir origens, a identidade é (tipo, id): o mesmo número em origens diferentes não é o mesmo concorrente.

Escrever a recursão

Uma CTE recursiva junta parte inicial (primeiras linhas) e passo (novas linhas a partir das anteriores), com o mesmo número de colunas compatíveis.

WITH RECURSIVE Numero(n) AS (
SELECT 1
UNION ALL
SELECT n + 1 FROM Numero WHERE n < 5
)
SELECT n FROM Numero ORDER BY n;

Produz 1 a 5. O filtro testa o valor anterior: < 5 para em 5; <= 5 produziria 6. A terminação tem de vir da consulta, não de um limite presumido do motor.

Numa hierarquia Categoria(id, idMae), começa na raiz e junta filhos por c.idMae = d.id, com profundidade 0 na raiz. A estrangeira garante a mãe, mas não proíbe ciclos: isso é regra adicional.

Terminar com ciclos

Com Aresta(1,2),(2,3),(3,1),(2,4), os alcançáveis de 1 são 1, 2, 3, 4:

Ficheiros do exemplo
Nós alcançáveis, mesmo com um ciclo
WITH RECURSIVE Alcancavel(id) AS (
SELECT 1
UNION
SELECT a.destino FROM Aresta AS a
JOIN Alcancavel AS r ON a.origem = r.id
)
SELECT id FROM Alcancavel ORDER BY id;
CREATE TABLE Aresta(origem INTEGER NOT NULL,
destino INTEGER NOT NULL, PRIMARY KEY(origem, destino));
INSERT INTO Aresta VALUES (1,2), (2,3), (3,1), (2,4);
Resultado

Executa a consulta para ver as tabelas.

UNION elimina tuplos já obtidos e trava o ciclo; UNION ALL seguiria sem parar. A deduplicação compara o tuplo inteiro: com profundidade, (1,0) e (1,3) são distintos e o ciclo reabre. Para caminhos, impede repetição de nós no caminho e limita a exploração.

O caso D’Hondt

Para MM mandatos: gera divisores 1 a MM (só isto é recursivo), cruza listas com divisores, calcula votos/divisor e fica com os MM maiores quocientes. Com A=100, B=60, C=40 e M=4M=4: 100/A, 60/B, 50/A, 40/C. A leva 2, B e C 1 cada. Usa divisão real e desempate explícito; o desempate por nome do exercício é convenção, não lei eleitoral.

Em SQLite, o passo recursivo não aceita agregações nem janelas: agrega no SELECT exterior.

Hierarquia e passos da recursão.

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