SQL da Semana #07 — LATERAL: subconsultas para cada linha

Subconsultas colocadas no FROM normalmente são independentes das tabelas que aparecem antes delas. Mas alguns problemas exigem que a subconsulta seja avaliada para cada linha externa. Um exemplo comum é buscar os três produtos mais vendidos de cada categoria. No PostgreSQL, LATERAL permite expressar essa dependência diretamente. O problema Considere as tabelas: CREATE TABLE categories ( category_id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY, name text NOT NULL UNIQUE ); CREATE TABLE products ( product_id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY, category_id bigint NOT NULL REFERENCES categories, name text NOT NULL, sales_count integer NOT NULL DEFAULT 0 ); Queremos listar cada categoria acompanhada dos três produtos com maior sales_count. ...

SQL da Semana #06 — Window Functions: rankings e acumulados

Agregações tradicionais reduzem várias linhas a um resultado por grupo. Isso é exatamente o que queremos ao calcular o total de vendas por vendedor. Mas e se precisarmos manter cada venda e, ao mesmo tempo, mostrar sua posição no ranking e o valor acumulado? Para esse tipo de problema, o SQL oferece funções de janela. O problema Considere uma tabela de vendas: CREATE TABLE vendas ( venda_id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY, vendedor_id bigint NOT NULL, realizada_em timestamptz NOT NULL, valor numeric(12, 2) NOT NULL CHECK (valor > 0) ); Queremos exibir cada venda com: ...

SQL da Semana #05 — CTE: organizando consultas complexas

Consultas SQL costumam crescer de maneira incremental. Primeiro precisamos filtrar os dados. Depois agregar por cliente, calcular uma média, comparar cada resultado com essa média e ordenar somente os casos mais relevantes. Quando todas essas etapas ficam aninhadas em uma única expressão, a consulta pode continuar correta, mas se torna difícil de ler e modificar. Uma Common Table Expression, ou CTE, permite dividir esse raciocínio em resultados nomeados. O problema Considere uma tabela com execuções de pipelines: ...

SQL da Semana #04 — UPSERT: inserindo ou atualizando com segurança

Integrações, cargas de dados e consumidores de eventos frequentemente precisam executar uma operação simples de descrever: Se o registro ainda não existe, insira. Se já existe, atualize. Esse comportamento é conhecido como upsert, combinação de update e insert. No PostgreSQL, ele pode ser implementado com INSERT ... ON CONFLICT. O problema Considere uma tabela que registra o estado mais recente de cada pipeline em uma data de referência: CREATE TABLE pipeline_status ( pipeline text NOT NULL, reference_date date NOT NULL, status text NOT NULL, attempts integer NOT NULL DEFAULT 1, updated_at timestamptz NOT NULL DEFAULT now(), CONSTRAINT pipeline_status_uk UNIQUE (pipeline, reference_date) ); Uma mesma execução pode ser informada novamente por retry, reprocessamento ou entrega duplicada de mensagem. ...

SQL da Semana #03 — DISTINCT ON: obtendo o registro mais recente por grupo

Em plataformas de dados, é comum armazenarmos o histórico de execuções de cada pipeline. Uma mesma rotina pode ter sido executada dezenas ou centenas de vezes, mas algumas consultas precisam mostrar apenas seu estado mais recente. No PostgreSQL, podemos resolver esse problema de forma concisa com DISTINCT ON. O problema Considere uma tabela que registra as execuções de pipelines: CREATE TABLE execucoes_pipeline ( id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY, pipeline text NOT NULL, status text NOT NULL, iniciado_em timestamptz NOT NULL, finalizado_em timestamptz ); Cada linha representa uma execução: ...

SQL da Semana #02 — FILTER: agregações condicionais mais claras

Em relatórios SQL, é comum precisarmos calcular diferentes totais a partir do mesmo conjunto de dados. Imagine uma tabela de pedidos com a seguinte estrutura: CREATE TABLE pedidos ( id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY, cliente_id bigint NOT NULL, status text NOT NULL, valor numeric(12, 2) NOT NULL, criado_em timestamp NOT NULL DEFAULT current_timestamp ); Queremos apresentar, em uma única consulta: quantidade total de pedidos; pedidos pagos; pedidos pendentes; pedidos cancelados; valor total dos pedidos pagos. A solução tradicional com CASE Uma forma comum de resolver o problema é colocar expressões CASE dentro das funções de agregação: ...

SQL da Semana #01 — RETURNING: obtendo dados sem fazer uma nova consulta

Ao inserir um registro no PostgreSQL, é comum precisar do identificador gerado pelo banco para continuar o processamento. Uma solução possível é executar o INSERT e, em seguida, fazer outra consulta. O PostgreSQL oferece uma alternativa mais direta: a cláusula RETURNING. O problema Considere uma tabela que armazena tarefas de processamento: CREATE TABLE jobs ( id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY, file_path text NOT NULL, status text NOT NULL DEFAULT 'pending', created_at timestamptz NOT NULL DEFAULT now() ); Depois de criar um job, a aplicação precisa conhecer o id, o estado inicial e a data atribuída pelo banco. ...

Privacidade

Gerenciar opções

Escolha quais tecnologias opcionais podem ser utilizadas. As necessárias permanecem ativas para o funcionamento e para as preferências de interface do site.

Necessários

Preferências de tema, menu e registro da sua escolha de privacidade.

Analytics

Ajuda a compreender acessos e uso do conteúdo por meio do Google Analytics 4.

Publicidade

Reserva sua escolha para o Google AdSense, que ainda não exibe anúncios no site.