■ Material de Apoio – Sistema de Logística
Alimentícia
Parte 1 – Roteiro de Exercícios
1. Listar todos os produtos cadastrados com sua categoria e unidade de medida.
2. Mostrar todos os lotes de produtos que já estão vencidos.
3. Consultar a quantidade de estoque atual de um produto específico (ex.: “Arroz 5kg”).
4. Listar todos os clientes cadastrados, ordenados pelo nome.
5. Mostrar todas as vendas realizadas em um determinado mês/ano.
6. Exibir os 5 produtos com maior quantidade em estoque (somando todos os armazéns).
7. Listar os produtos perecíveis cujo vencimento está em até 10 dias.
8. Mostrar o saldo de estoque por armazém (agrupando por produto e local).
9. Consultar as entradas e saídas de estoque de um produto específico, agrupadas por mês.
10. Listar os embarques pendentes (sem data de realização) e o cliente associado.
11. Criar um ranking de clientes pelo volume financeiro comprado no último ano.
12. Exibir o giro de estoque (entradas x saídas) dos últimos 6 meses por produto.
13. Consultar os produtos que já estão sem estoque em pelo menos 1 armazém.
14. Identificar as entregas atrasadas e calcular quantos dias de atraso houve.
15. Mostrar o lucro bruto estimado por venda (quantidade × preço unitário).
16. Listar os produtos que nunca foram vendidos.
17. Encontrar clientes que compraram mais de 3 vezes em um mesmo mês.
18. Calcular o tempo médio entre a data de venda e a entrega real.
19. Consultar os 3 armazéns mais movimentados em quantidade de saídas.
20. Gerar um relatório de saldo total de estoque em valor financeiro (quantidade × preço médio).
Parte 2 – Gabarito SQL
A seguir estão as consultas SQL correspondentes aos exercícios:
-- ■ Gabarito SQL – Sistema de Logística Alimentícia
-- Parte 1 – Consultas Básicas
-- 1. Produtos cadastrados
SELECT id_produto, nome, categoria, unidade_medida FROM produto;
-- 2. Lotes vencidos
SELECT [Link], l.codigo_lote, l.data_validade
FROM lote l
JOIN produto p ON l.id_produto = p.id_produto
WHERE l.data_validade < CURDATE();
-- 3. Estoque de um produto específico
SELECT [Link], SUM([Link]) AS total_estoque
FROM estoque_saldo es
JOIN produto p ON es.id_produto = p.id_produto
WHERE [Link] = 'Arroz 5kg'
GROUP BY [Link];
-- 4. Clientes ordenados pelo nome
SELECT id_cliente, nome, cnpj_cpf, endereco FROM cliente ORDER BY nome;
-- 5. Vendas em um mês específico
SELECT * FROM venda WHERE DATE_FORMAT(data_venda, '%Y-%m') = '2025-09';
-- Parte 2 – Consultas Intermediárias
-- 6. Top 5 produtos em estoque
SELECT [Link], SUM([Link]) AS quantidade_total
FROM estoque_saldo es
JOIN produto p ON es.id_produto = p.id_produto
GROUP BY [Link]
ORDER BY quantidade_total DESC
LIMIT 5;
-- 7. Produtos perecíveis próximos do vencimento (10 dias)
SELECT [Link], l.codigo_lote, l.data_validade
FROM lote l
JOIN produto p ON l.id_produto = p.id_produto
WHERE [Link] = TRUE
AND l.data_validade <= DATE_ADD(CURDATE(), INTERVAL 10 DAY);
-- 8. Saldo de estoque por armazém
SELECT [Link] AS armazem, [Link] AS produto, SUM([Link]) AS quantidade
FROM estoque_saldo es
JOIN armazem a ON es.id_armazem = a.id_armazem
JOIN produto p ON es.id_produto = p.id_produto
GROUP BY [Link], [Link];
-- 9. Entradas e saídas por mês
SELECT [Link], DATE_FORMAT(em.data_movimento, '%Y-%m') AS mes,
SUM(CASE WHEN em.tipo_movimento = 'E' THEN [Link] ELSE 0 END) AS entradas,
SUM(CASE WHEN em.tipo_movimento = 'S' THEN [Link] ELSE 0 END) AS saidas
FROM estoque_movimento em
JOIN produto p ON em.id_produto = p.id_produto
WHERE [Link] = 'Arroz 5kg'
GROUP BY [Link], mes
ORDER BY mes;
-- 10. Embarques pendentes
SELECT e.id_embarque, [Link] AS cliente, e.data_prevista
FROM embarque e
JOIN cliente c ON e.id_cliente = c.id_cliente
WHERE e.data_realizada IS NULL;
-- Parte 3 – Consultas Avançadas
-- 11. Ranking de clientes (último ano)
SELECT [Link], SUM([Link] * iv.preco_unitario) AS total_comprado
FROM venda v
JOIN item_venda iv ON v.id_venda = iv.id_venda
JOIN cliente c ON v.id_cliente = c.id_cliente
WHERE YEAR(v.data_venda) = YEAR(CURDATE())
GROUP BY [Link]
ORDER BY total_comprado DESC;
-- 12. Giro de estoque últimos 6 meses
SELECT [Link], DATE_FORMAT(em.data_movimento, '%Y-%m') AS mes,
SUM(CASE WHEN em.tipo_movimento = 'E' THEN [Link] ELSE 0 END) AS entradas,
SUM(CASE WHEN em.tipo_movimento = 'S' THEN [Link] ELSE 0 END) AS saidas
FROM estoque_movimento em
JOIN produto p ON em.id_produto = p.id_produto
WHERE em.data_movimento >= DATE_SUB(CURDATE(), INTERVAL 6 MONTH)
GROUP BY [Link], mes
ORDER BY mes DESC;
-- 13. Produtos sem estoque em algum armazém
SELECT [Link], [Link] AS armazem
FROM estoque_saldo es
JOIN produto p ON es.id_produto = p.id_produto
JOIN armazem a ON es.id_armazem = a.id_armazem
WHERE [Link] = 0;
-- 14. Entregas atrasadas com dias de atraso
SELECT e.id_embarque, [Link] AS cliente,
e.data_prevista, e.data_realizada,
DATEDIFF(e.data_realizada, e.data_prevista) AS dias_atraso
FROM embarque e
JOIN cliente c ON e.id_cliente = c.id_cliente
WHERE e.data_realizada > e.data_prevista;
-- 15. Lucro bruto por venda
SELECT v.id_venda, [Link] AS cliente,
SUM([Link] * iv.preco_unitario) AS valor_total
FROM venda v
JOIN item_venda iv ON v.id_venda = iv.id_venda
JOIN cliente c ON v.id_cliente = c.id_cliente
GROUP BY v.id_venda, [Link];
-- Parte 4 – Desafios Extras
-- 16. Produtos nunca vendidos
SELECT [Link]
FROM produto p
LEFT JOIN item_venda iv ON p.id_produto = iv.id_produto
WHERE iv.id_produto IS NULL;
-- 17. Clientes com mais de 3 compras no mesmo mês
SELECT [Link], DATE_FORMAT(v.data_venda, '%Y-%m') AS mes, COUNT(*) AS
total_vendas
FROM venda v
JOIN cliente c ON v.id_cliente = c.id_cliente
GROUP BY [Link], mes
HAVING COUNT(*) > 3;
-- 18. Tempo médio entre venda e entrega
SELECT [Link], AVG(DATEDIFF(e.data_realizada, v.data_venda)) AS media_dias
FROM venda v
JOIN embarque e ON v.id_cliente = e.id_cliente
JOIN cliente c ON v.id_cliente = c.id_cliente
WHERE e.data_realizada IS NOT NULL
GROUP BY [Link];
-- 19. Armazéns mais movimentados (saídas)
SELECT [Link], SUM([Link]) AS total_saidas
FROM estoque_movimento em
JOIN armazem a ON em.id_armazem = a.id_armazem
WHERE em.tipo_movimento = 'S'
GROUP BY [Link]
ORDER BY total_saidas DESC
LIMIT 3;
-- 20. Valor financeiro do estoque atual
SELECT [Link], SUM([Link] * iv.preco_unitario) AS valor_estoque
FROM estoque_saldo es
JOIN produto p ON es.id_produto = p.id_produto
JOIN item_venda iv ON es.id_produto = iv.id_produto
GROUP BY [Link]
ORDER BY valor_estoque DESC;