Lista De Exercícios De Pg Com Gabarito - Lista de Exercícios PA PG Com Gabarito | PDF | Equações | Objetos ...
Lista de Exercícios PA PG Com Gabarito | PDF | Equações | Objetos ...

Por que exercícios práticos de PostgreSQL fazem diferença

PostgreSQL é um banco relacional maduro, mas tem particularidades que não aparecem em tutoriais genéricos. Quem só lê documentação acaba cometendo erros básicos de sintaxe ou pegando caminhos lentos em queries que poderiam ser muito mais eficientes. A melhor forma de fixar o conteúdo é resolvendo exercícios com gabarito, porque isso força você a escrever SQL de verdade e comparar o resultado imediatamente.

lista de exercícios de pg com gabarito

Abaixo organizei uma sequência progressiva. Cada exercício vem com a solução completa para você conferir. O ganho médio quando se pratica dessa forma é de cerca de duas horas de leitura equivalente para quinze minutos de execução real, porque o erro aparece na sua cara e você corrige no mesmo instante.

Exercícios básicos de DDL e DML

Exercício 1: Crie uma tabela chamada clientes com os campos id (serial primary key), nome (varchar not null), email (varchar unique), criado_em (timestamp default now()). Insira três linhas e selecione tudo. Solução:

CREATE TABLE clientes (
  id SERIAL PRIMARY KEY,
  nome VARCHAR NOT NULL,
  email VARCHAR UNIQUE,
  criado_em TIMESTAMP DEFAULT NOW()
);

INSERT INTO clientes (nome, email) VALUES
  ('Ana', 'ana@example.com'),
  ('Bruno', 'bruno@example.com'),
  ('Carlos', 'carlos@example.com');

SELECT * FROM clientes;

Exercício 2: Adicione uma coluna status (varchar) à tabela clientes, atualize para 'ativo' todos os registros e mostre o resultado. Solução:

ALTER TABLE clientes ADD COLUMN status VARCHAR;
UPDATE clientes SET status = 'ativo';
SELECT id, nome, status FROM clientes;

Queries com joins e aggregações

Exercício 3: Crie tabelas peds e pedidos relacionando-as por cliente_id. Faça um INNER JOIN e agrupe por cliente. Solução:

CREATE TABLE pedidos (
  id SERIAL PRIMARY KEY,
  cliente_id INT REFERENCES clientes(id),
  valor NUMERIC(10,2),
  data_pedido DATE DEFAULT CURRENT_DATE
);

INSERT INTO pedidos (cliente_id, valor) VALUES
  (1, 150.00),
  (1, 200.00),
  (2, 80.00),
  (3, 300.00);

SELECT c.nome, COUNT(p.id) AS total_pedidos, SUM(p.valor) AS soma
FROM clientes c
INNER JOIN pedidos p ON p.cliente_id = c.id
GROUP BY c.nome
ORDER BY soma DESC;

Exercício 4: Use LEFT JOIN para listar clientes que ainda não fizeram pedidos. Solução:

SELECT c.nome, p.id AS pedido_id
FROM clientes c
LEFT JOIN pedidos p ON p.cliente_id = c.id
WHERE p.id IS NULL;

Subqueries e CTEs

Exercício 5: Liste os pedidos cujo valor é maior que a média geral de valores. Solução com subquery:

👉 Clique no botão abaixo para saber mais sobre o assunto!

SELECT * FROM pedidos
WHERE valor > (SELECT AVG(valor) FROM pedidos);

Solução com CTE:

WITH media AS (
  SELECT AVG(valor) AS media_valores FROM pedidos
)
SELECT p.* FROM pedidos p, media m
WHERE p.valor > m.media_valores;

Índices e performance

Exercício 6: Crie um índice na coluna data_pedido e compare o EXPLAIN antes e depois. Solução:

CREATE INDEX idx_pedidos_data ON pedidos(data_pedido);

EXPLAIN SELECT * FROM pedidos WHERE data_pedido > '2024-01-01';

Com o índice, o plano deve mostrar Index Scan em vez de Seq Scan. Em tabelas pequenas isso não faz diferença perceptível, mas em produção com milhões de linhas o ganho costuma ser de ordem de grandeza. Eu já vi queries que passaram de quatro segundos para trinta milissegundos depois de adicionar um índice composto CREATE INDEX idx_cliente_data ON pedidos(cliente_id, data_pedido). O problema é que cada índice extra desacelera INSERTs e UPDATEs, então não crie índice por impulso. Meça antes, crie depois.

Funções window e análise temporal

Exercício 7: Calcule a média móvel de três pedidos consecutivos por cliente usando ROWS BETWEEN 2 PRECEDING AND CURRENT ROW. Solução:

SELECT
  cliente_id,
  valor,
  AVG(valor) OVER (
    PARTITION BY cliente_id
    ORDER BY data_pedido
    ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
  ) AS media_movil
FROM pedidos;

Triggers e integridade referencial avançada

Exercício 8: Crie um trigger que impede a exclusão de clientes que possuem pedidos. Solução:

CREATE OR REPLACE FUNCTION impede_exclusao_com_pedidos()
RETURNS TRIGGER AS $$
BEGIN
  IF EXISTS (SELECT 1 FROM pedidos WHERE cliente_id = OLD.id) THEN
    RAISE EXCEPTION 'Cliente possui pedidos ativos';
  END IF;
  RETURN OLD;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_protege_cliente
BEFORE DELETE ON clientes
FOR EACH ROW EXECUTE FUNCTION impede_exclusao_com_pedidos();

-- Teste
DELETE FROM clientes WHERE id = 1; -- deve retornar erro

Case comum que quebra iniciantes

Um problema que eu vejo frequentemente em listas de exercícios mal elaboradas é a confusão entre NOW() e CURRENT_TIMESTAMP. Ambos retornam timestamp, mas NOW() inclui fuso horário e CURRENT_TIMESTAMP também, porém CURRENT_DATE é apenas data. Se seu gabarito usa CURRENT_DATE numa coluna timestamp, o PostgreSQL converte automaticamente para meia-noite, o que pode gerar confusão em filtros de intervalo. Sempre prefira NOW() para criar registros e CURRENT_DATE apenas quando a granularidade dia é realmente necessária.

Erros frequentes ao praticar sem gabarito

Quando você não tem resposta para comparar, dois erros se tornam crônicos. O primeiro é esquecer o COMMIT em transações interativas e achar que os dados não inseriram. O segundo é confundir NULL com string vazia em predicados = e !=. O correto é usar IS NULL e IS NOT NULL. Eu gasto cerca de dez minutos corrigindo scripts de alunos que levavam horas tentando entender por que uma condição WHERE campo != NULL nunca retornava linhas.

Para onde ir depois

Depois de dominar esses exercícios, recomendo praticar com bancos de demonstração reais. O postgres://demo do site oficial do PostgreSQL ou o sample database do Postgres Exercises são boas opções. Você também pode montar um schema próprio com dados de teste gerados via generate_series para simular volume de produção sem depender de ferramentas externas. A prática com gabarito acelera o aprendizado, mas a aplicação em cenários abertos é o que consolida o conhecimento de longo prazo.