This commit is contained in:
IdalecioSch
2026-06-24 18:46:44 -03:00
commit 8c688729db
6 changed files with 512 additions and 0 deletions
+68
View File
@@ -0,0 +1,68 @@
CREATE TYPE tipo_contato AS ENUM ('email', 'telefone', 'celular', 'whatsapp');
CREATE TABLE cliente (
id SERIAL PRIMARY KEY,
cpf CHAR(11) NOT NULL,
nome VARCHAR(50) NOT NULL
);
CREATE TABLE cor (
id SERIAL PRIMARY KEY,
descricao VARCHAR(20) NOT NULL,
fundo BOOLEAN NOT NULL,
frase BOOLEAN NOT NULL
);
CREATE TABLE material (
id SERIAL PRIMARY KEY,
descricao VARCHAR(20) NOT NULL,
valor_letra DECIMAL(10,2) NOT NULL,
custo DECIMAL(10,2) NOT NULL
);
CREATE TABLE desconto (
id SERIAL PRIMARY KEY,
valor_minimo DECIMAL(10,2) NOT NULL,
valor_maximo DECIMAL(10,2) NOT NULL,
percentual DECIMAL(5,2) NOT NULL
);
CREATE TABLE contato (
id SERIAL PRIMARY KEY,
cliente_id INTEGER NOT NULL,
tipo tipo_contato NOT NULL,
informacao VARCHAR(50) NOT NULL,
CONSTRAINT fk_contato_cliente FOREIGN KEY (cliente_id) REFERENCES cliente(id)
);
CREATE TABLE placa (
id SERIAL PRIMARY KEY,
largura INTEGER NOT NULL,
altura INTEGER NOT NULL,
material_id INTEGER NOT NULL,
CONSTRAINT fk_placa_material FOREIGN KEY (material_id) REFERENCES material(id)
);
CREATE TABLE encomenda (
id SERIAL PRIMARY KEY,
data TIMESTAMP NOT NULL,
entrega TIMESTAMP NOT NULL,
cliente_id INTEGER NOT NULL,
desconto_id INTEGER NOT NULL,
CONSTRAINT fk_encomenda_cliente FOREIGN KEY (cliente_id) REFERENCES cliente(id),
CONSTRAINT fk_encomenda_desconto FOREIGN KEY (desconto_id) REFERENCES desconto(id)
);
CREATE TABLE item (
id SERIAL PRIMARY KEY,
encomenda_id INTEGER NOT NULL,
placa_id INTEGER NOT NULL,
frase VARCHAR(50) NOT NULL,
cor_fundo_id INTEGER NOT NULL,
cor_frase_id INTEGER NOT NULL,
CONSTRAINT fk_item_encomenda FOREIGN KEY (encomenda_id) REFERENCES encomenda(id),
CONSTRAINT fk_item_placa FOREIGN KEY (placa_id) REFERENCES placa(id),
CONSTRAINT fk_item_cor_fundo FOREIGN KEY (cor_fundo_id) REFERENCES cor(id),
CONSTRAINT fk_item_cor_frase FOREIGN KEY (cor_frase_id) REFERENCES cor(id)
);
+31
View File
@@ -0,0 +1,31 @@
ALTER TABLE encomenda
ADD COLUMN valor DECIMAL(10,2) NOT NULL DEFAULT 0.00;
CREATE TABLE recebimento (
id SERIAL PRIMARY KEY,
encomenda_id INTEGER NOT NULL,
sinal DECIMAL(10,2) NOT NULL,
data_sinal TIMESTAMP NOT NULL,
restante DECIMAL(10,2) NOT NULL,
data_restante TIMESTAMP NOT NULL,
CONSTRAINT fk_recebimento_encomenda
FOREIGN KEY (encomenda_id) REFERENCES encomenda(id)
);
ALTER TABLE encomenda
DROP CONSTRAINT fk_encomenda_desconto;
ALTER TABLE encomenda
DROP COLUMN desconto_id;
DROP TABLE desconto;
ALTER TABLE encomenda
ADD COLUMN situacao VARCHAR(10) NOT NULL DEFAULT 'Aberta'
CONSTRAINT chk_encomenda_situacao CHECK (situacao IN ('Aberta', 'Fechada'));
+104
View File
@@ -0,0 +1,104 @@
### 3 — Trigger antes de insercao pra poder ja ser chamada ao inserir dados
Fun trigger 1 atualiza encomenda.valor quando insere/altera/exclui
Calcula o valor da encomenda quando adiciona um novo item no pedido, formula: `material.custo + LENGTH(item.frase) × material.valor_letra`.
```sql
CREATE FUNCTION fun_att_valor_enc()
RETURNS TRIGGER AS $$
DECLARE
val_enc_id INTEGER;
BEGIN
IF TG_OP = 'DELETE' THEN
val_enc_id := OLD.encomenda_id; -- old pq pega o item.encomenda id antes de apagar
ELSE
val_enc_id := NEW.encomenda_id; -- new pq pega o item.encomenda_id depois de alterar/inserir
END IF;
UPDATE encomenda
SET valor = (
SELECT COALESCE(
SUM(m.custo + LENGTH(i.frase) * m.valor_letra),
0.00
)
-- Coalese pq ele tenta pegar sum, se ficar null, retorna 0.00 msm, como um operador ternario
FROM item i
JOIN placa p ON p.id = i.placa_id
JOIN material m ON m.id = p.material_id
WHERE i.encomenda_id = val_enc_id
)
WHERE id = val_enc_id;
IF TG_OP = 'UPDATE' AND OLD.encomenda_id <> NEW.encomenda_id THEN
UPDATE encomenda
SET valor = (
SELECT COALESCE(
SUM(m.custo + LENGTH(i.frase) * m.valor_letra),
0.00
)
FROM item i
JOIN placa p ON p.id = i.placa_id
JOIN material m ON m.id = p.material_id
WHERE i.encomenda_id = OLD.encomenda_id
)
WHERE id = OLD.encomenda_id;
END IF;
IF TG_OP = 'DELETE' THEN
RETURN OLD;
ELSE
RETURN NEW;
END IF;
END;
$$ LANGUAGE plpgsql;
```
fun trigger 2 — registra recebimento quando fecha encomenda
Quando encomenda.situacao() passa de aberta pra Fechada, bota uma linha em
recebimento com:
- snal = 1/2 do valor total -> vence na data encomenda.data
- resto = restante -> vence na data de encomenda.entrega
```sql
CREATE OR REPLACE FUNCTION fun_fechar_encomenda()
RETURNS TRIGGER AS $$
BEGIN
-- so quando muda de Aberta pra Fechada
IF NEW.situacao = 'Fechada' AND OLD.situacao = 'Aberta' THEN
INSERT INTO recebimento (encomenda_id, sinal, data_sinal, restante, data_restante)
VALUES (
NEW.id,
(NEW.valor * 0.50),
NEW.data,
(NEW.valor * 0.50),
NEW.entrega
);
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
```
---
triggers
```sql
CREATE TRIGGER trg_fechar_encomenda
AFTER UPDATE ON encomenda
FOR EACH ROW
EXECUTE FUNCTION fun_fechar_encomenda();
CREATE TRIGGER trg_att_valor_enc
AFTER INSERT OR UPDATE OR DELETE ON item
FOR EACH ROW
EXECUTE FUNCTION fun_att_valor_enc();
```
+132
View File
@@ -0,0 +1,132 @@
INSERT INTO cliente (cpf, nome) VALUES
('11122233344', 'Marco Aurelio'),
('22233344455', 'Fernando Bastos'),
('33344455566', 'Fabiano Gabardo'),
('44455566677', 'Jullian Hermann'),
('55566677788', 'Cleber Nardelli');
INSERT INTO material (descricao, valor_letra, custo) VALUES
('Aluminio', 2.50, 15.00),
('Plutonio', 1.50, 8.00),
('Acrilico', 3.00, 20.00);
INSERT INTO placa (largura, altura, material_id) VALUES
(20, 10, 1), -- Aluminio
(30, 15, 2), -- Plutonio
(40, 20, 3), -- Acrilico
(25, 12, 1), -- Aluminio
(35, 18, 2); -- Plutonio
INSERT INTO cor (descricao, fundo, frase) VALUES
('Branco', TRUE, FALSE),
('Preto', FALSE, TRUE),
('Vermelho', TRUE, TRUE),
('Azul', TRUE, TRUE),
('Amarelo', TRUE, FALSE),
('Verde', TRUE, TRUE),
('Laranja', TRUE, FALSE),
('Cinza', FALSE, TRUE);
INSERT INTO encomenda (data, entrega, cliente_id, valor, situacao) VALUES
-- Marco Aurelio
('2026-01-10 09:00', '2026-01-20 18:00', 1, 0.00, 'Aberta'),
('2026-02-05 10:00', '2026-02-15 18:00', 1, 0.00, 'Aberta'),
('2026-03-12 11:00', '2026-03-22 18:00', 1, 0.00, 'Aberta'),
('2026-04-18 14:00', '2026-04-28 18:00', 1, 0.00, 'Aberta'),
-- Fernando Bastos
('2026-01-15 09:30', '2026-01-25 18:00', 2, 0.00, 'Aberta'),
('2026-02-20 10:30', '2026-03-02 18:00', 2, 0.00, 'Aberta'),
('2026-03-25 11:30', '2026-04-04 18:00', 2, 0.00, 'Aberta'),
('2026-04-30 14:30', '2026-05-10 18:00', 2, 0.00, 'Aberta'),
-- Fabiano Gabardo
('2026-01-20 08:00', '2026-01-30 18:00', 3, 0.00, 'Aberta'),
('2026-02-25 09:00', '2026-03-07 18:00', 3, 0.00, 'Aberta'),
('2026-03-30 10:00', '2026-04-09 18:00', 3, 0.00, 'Aberta'),
('2026-05-05 15:00', '2026-05-15 18:00', 3, 0.00, 'Aberta'),
-- Jullian Hermann
('2026-01-25 09:00', '2026-02-04 18:00', 4, 0.00, 'Aberta'),
('2026-02-28 10:00', '2026-03-10 18:00', 4, 0.00, 'Aberta'),
('2026-04-02 11:00', '2026-04-12 18:00', 4, 0.00, 'Aberta'),
('2026-05-08 14:00', '2026-05-18 18:00', 4, 0.00, 'Aberta'),
-- Cleber Nardelli
('2026-02-01 08:30', '2026-02-11 18:00', 5, 0.00, 'Aberta'),
('2026-03-07 09:30', '2026-03-17 18:00', 5, 0.00, 'Aberta'),
('2026-04-10 10:30', '2026-04-20 18:00', 5, 0.00, 'Aberta'),
('2026-05-15 15:30', '2026-05-25 18:00', 5, 0.00, 'Aberta');
INSERT INTO item (encomenda_id, placa_id, frase, cor_fundo_id, cor_frase_id) VALUES
(1, 1, 'Proibido Entrar', 1, 2),
(1, 2, 'Saída Emergência', 3, 8),
(2, 3, 'Cuidado Elétrico', 4, 2),
(2, 4, 'Área Restrita', 5, 3),
(3, 5, 'Bem-vindo', 6, 2),
(3, 1, 'Atenção Obra', 1, 4),
(4, 2, 'Proibido Fumar', 3, 2),
(4, 3, 'Silêncio Hospital', 4, 8),
(5, 4, 'Loja Aberta', 7, 2),
(5, 5, 'Use EPI', 1, 6),
(6, 1, 'Recepção', 5, 4),
(6, 2, 'Banheiro Fem.', 6, 2),
(7, 3, 'Banheiro Masc.', 3, 8),
(7, 4, 'Piso Escorregadio', 5, 2),
(8, 5, 'Estacionamento', 1, 3),
(8, 1, 'Proibido Parar', 3, 2),
(9, 2, 'Entrada Proibida', 4, 2),
(9, 3, 'Piso Molhado', 7, 4),
(10, 4, 'Cuidado com o Cão', 1, 6),
(10, 5, 'Velocidade 30 km', 5, 2),
(11, 1, 'Portaria', 6, 2),
(11, 2, 'Segurança 24h', 1, 4),
(11, 3, 'Guarita', 3, 8),
(12, 4, 'Direção Proibida', 4, 2),
(12, 5, 'Pare', 3, 8),
(12, 1, 'Dê a Preferência', 5, 2),
(13, 2, 'Depósito', 1, 3),
(13, 3, 'Almoxarifado', 6, 2),
(13, 4, 'Produção', 4, 8),
(14, 5, 'Escritório', 1, 4),
(14, 1, 'Sala de Reunião', 3, 2),
(14, 2, 'TI', 5, 6),
(15, 3, 'Financeiro', 6, 2),
(15, 4, 'RH', 1, 4),
(15, 5, 'Diretoria', 4, 8),
(16, 1, 'Marketing', 3, 2),
(16, 2, 'Comercial', 7, 4),
(16, 3, 'Logística', 1, 6),
(17, 4, 'Manutenção', 5, 2),
(17, 5, 'Qualidade', 6, 8),
(17, 1, 'Expedição', 3, 4),
(18, 2, 'Controle de Acesso', 1, 2),
(18, 3, 'Câmeras Ativas', 4, 8),
(18, 4, 'Monitorado 24 horas', 3, 2),
(19, 5, 'Saída', 6, 2),
(19, 1, 'Entrada', 1, 4),
(19, 2, 'Carga e Descarga', 5, 3),
(20, 3, 'Refeitório', 7, 2),
(20, 4, 'Vestiário', 6, 8),
(20, 5, 'Emergência', 3, 2);
UPDATE encomenda SET situacao = 'Fechada'
WHERE id IN (1, 2, 5, 6, 9, 13, 17);
+120
View File
@@ -0,0 +1,120 @@
Consulta 1 — `SELECT … FROM … JOIN`
> Listar todos os itens com dados da placa, material e nome do cliente.
```sql
SELECT
e.id AS encomenda_id,
c.nome AS cliente,
i.frase,
p.largura || 'x' || p.altura AS dimensao_cm,
m.descricao AS material
FROM item i
JOIN encomenda e ON e.id = i.encomenda_id
JOIN cliente c ON c.id = e.cliente_id
JOIN placa p ON p.id = i.placa_id
JOIN material m ON m.id = p.material_id;
```
---
Consulta 2 — `SELECT … FROM … JOIN … WHERE`
> Encomendas abertas de um cliente específico, com valor acima de zero.
```sql
SELECT
e.id,
e.data,
e.entrega,
e.valor,
c.nome AS cliente
FROM encomenda e
JOIN cliente c ON c.id = e.cliente_id
WHERE c.nome = 'Ana Silva'
AND e.situacao = 'Aberta'
AND e.valor > 0
ORDER BY e.data;
```
---
Consulta 3 — `SELECT … FROM … JOIN … GROUP BY`
> Quantidade de itens e valor total por encomenda.
```sql
SELECT
e.id AS encomenda_id,
c.nome AS cliente,
e.situacao,
COUNT(i.id) AS total_itens,
e.valor AS valor_encomenda
FROM encomenda e
JOIN cliente c ON c.id = e.cliente_id
JOIN item i ON i.encomenda_id = e.id
GROUP BY e.id, c.nome, e.situacao, e.valor
ORDER BY total_itens DESC;
```
---
Consulta 4 — `SELECT … FROM … JOIN … WHERE … GROUP BY`
> Total de encomendas e receita por cliente, apenas para encomendas fechadas.
```sql
SELECT
c.nome AS cliente,
COUNT(e.id) AS total_encomendas,
SUM(e.valor) AS receita_total
FROM encomenda e
JOIN cliente c ON c.id = e.cliente_id
WHERE e.situacao = 'Fechada'
GROUP BY c.id, c.nome
ORDER BY receita_total DESC;
```
---
Consulta 5 — `SELECT … FROM … JOIN … GROUP BY … HAVING`
> Encomendas com mais de 2 itens (independente de status).
```sql
SELECT
e.id AS encomenda_id,
c.nome AS cliente,
e.situacao,
COUNT(i.id) AS total_itens
FROM encomenda e
JOIN cliente c ON c.id = e.cliente_id
JOIN item i ON i.encomenda_id = e.id
GROUP BY e.id, c.nome, e.situacao
HAVING COUNT(i.id) > 2
ORDER BY total_itens DESC;
```
---
Consulta 6 — `SELECT … FROM … JOIN … WHERE … GROUP BY … HAVING`
> Materiais usados em encomendas abertas a partir de março de 2024,
> com valor médio por item acima de R$ 30,00.
```sql
SELECT
m.descricao AS material,
COUNT(i.id) AS total_itens,
ROUND(AVG(m.custo + LENGTH(i.frase) * m.valor_letra), 2) AS valor_medio_item
FROM item i
JOIN encomenda e ON e.id = i.encomenda_id
JOIN placa p ON p.id = i.placa_id
JOIN material m ON m.id = p.material_id
WHERE e.situacao = 'Aberta'
AND e.data >= '2024-03-01'
GROUP BY m.id, m.descricao
HAVING AVG(m.custo + LENGTH(i.frase) * m.valor_letra) > 30
ORDER BY valor_medio_item DESC;
```
+57
View File
@@ -0,0 +1,57 @@
# 5.5 — Views
---
View 1 — 3 clientes com maior receita
Considera apenas encomendas com `situacao = 'Fechada'`
```sql
CREATE OR REPLACE VIEW viww_top3_clientes_receita AS
SELECT
c.id,
c.nome,
c.cpf,
COUNT(e.id) AS total_encomendas,
SUM(e.valor) AS receita_total
FROM cliente c
JOIN encomenda e ON e.cliente_id = c.id
WHERE e.situacao = 'Fechada'
GROUP BY c.id, c.nome, c.cpf
ORDER BY receita_total DESC
LIMIT 3;
```
```sql
SELECT * FROM viww_top3_clientes_receita;
```
---
View 2 — Valor arrecadado por placa
Soma o valor gerado por cada tipo de placa nas encomendas fechadas.
O valor por item é calculado como `material.custo + LENGTH(frase) × material.valor_letra`.
```sql
CREATE VIEW view_valor_por_placa AS
SELECT
p.id AS placa_id,
p.largura || ' x ' || p.altura || ' cm' AS dimensao,
m.descricao AS material,
COUNT(i.id) AS total_vendas,
ROUND(
SUM(m.custo + LENGTH(i.frase) * m.valor_letra), 2
) AS valor_arrecadado
FROM placa p
JOIN item i ON i.placa_id = p.id
JOIN encomenda e ON e.id = i.encomenda_id
JOIN material m ON m.id = p.material_id
WHERE e.situacao = 'Fechada'
GROUP BY p.id, p.largura, p.altura, m.descricao
ORDER BY valor_arrecadado DESC;
```
```sql
SELECT * FROM view_valor_por_placa;
```