@@ -370,7 +370,7 @@ Order_items (
370370
371371## 10. Entities Relational Diagram
372372
373- <img src =" images\er-diagram.png " width = " 200px " >
373+ <img src =" images\er-diagram.png " >
374374
375375## 11. Relational Database
376376
@@ -1673,4 +1673,330 @@ INSERT INTO Order_Items (id_order, id_product, quantity, unit_value) VALUES (
16731673
16741674## 13. SQL Simple Queries
16751675
1676- ## 14. SQL Advanced Queries
1676+ -- 1. Listar todos os clientes que não têm canal de aquisição definido (NULL)
1677+ SELECT id_cliente, nome, canal_aquisicao
1678+ FROM Clientes
1679+ WHERE canal_aquisicao IS NULL;
1680+
1681+ -- 2. Listar os 10 clientes mais recentes (por ordem decrescente de data de criação)
1682+ SELECT id_cliente, nome, data_criacao
1683+ FROM Clientes
1684+ ORDER BY data_criacao DESC
1685+ LIMIT 10;
1686+
1687+ -- 3. Mostrar todos os produtos cujo nome contém "Gold"
1688+ SELECT id_produto, designacao
1689+ FROM Produtos
1690+ WHERE designacao LIKE '%Gold%';
1691+
1692+ -- 4. Listar produtos do tipo cerveja com preço entre 2.5 e 4.0 EUR
1693+ SELECT id_produto, designacao, preco_venda
1694+ FROM Produtos
1695+ WHERE tipo_de_produto = 'cerveja'
1696+ AND preco_venda BETWEEN 2.5 AND 4.0
1697+ ORDER BY preco_venda ASC;
1698+
1699+ -- 5. Quantidade de clientes por canal de aquisição (GROUP BY e COUNT)
1700+ SELECT canal_aquisicao, COUNT(* ) AS total_clientes
1701+ FROM Clientes
1702+ GROUP BY canal_aquisicao
1703+ ORDER BY total_clientes DESC;
1704+
1705+ -- 6. Listar clientes cujo nome começa por "A"
1706+ SELECT id_cliente, nome
1707+ FROM Clientes
1708+ WHERE nome LIKE 'A%';
1709+
1710+ -- 7. Mostrar fornecedores com email que termina em ".pt"
1711+ SELECT id_fornecedor, nome_empresa
1712+ FROM Fornecedores
1713+ WHERE email LIKE '%.pt';
1714+
1715+ -- 8. Listar encomendas pendentes de pagamento (AND/OR e DESC)
1716+ SELECT id_encomenda, id_fornecedor, estado_pagamento, data_encomenda
1717+ FROM encomendas
1718+ WHERE estado_pagamento = 'pendente'
1719+ ORDER BY data_encomenda DESC;
1720+
1721+ -- 9. Mostrar clientes que recebem newsletter e autorizaram GDPR
1722+ SELECT id_cliente, nome
1723+ FROM Clientes
1724+ WHERE newsletter = 1 AND autorizacao = 1;
1725+
1726+ -- 10. Listar produtos com stock abaixo do mínimo
1727+ SELECT id_produto, designacao, stock_atual, stock_minimo
1728+ FROM Produtos
1729+ WHERE stock_atual < stock_minimo;
1730+
1731+ -- 11. Produtos distintos do tipo “snacks”
1732+ SELECT DISTINCT designacao, tipo_de_produto
1733+ FROM Produtos
1734+ WHERE tipo_de_produto = 'snacks';
1735+
1736+ -- 12. Mostrar todos os funcionários cujo telemóvel NÃO começa por “91”
1737+ SELECT id_funcionario, nome, nr_telemovel
1738+ FROM Funcionarios
1739+ WHERE NOT nr_telemovel LIKE '91%';
1740+
1741+ -- 13. Clientes cujo NIF está entre 100000000 e 200000000 (BETWEEN)
1742+ SELECT id_cliente, nome, nif
1743+ FROM Clientes
1744+ WHERE nif BETWEEN 100000000 AND 200000000;
1745+
1746+ -- 14. Listar todas as avaliações com NOT visibilidade
1747+ SELECT id_cliente, avaliacao, comentario
1748+ FROM Avaliacao
1749+ WHERE NOT visibilidade;
1750+
1751+ -- 15. Produtos ordenados por preço de compra, de forma ascendente
1752+ SELECT id_produto, designacao, preco_compra
1753+ FROM Produtos
1754+ ORDER BY preco_compra ASC;
1755+
1756+ -- 16. Mostrar encomendas com estado "cancelado" OU valor superior a 25 EUR
1757+ SELECT id_encomenda, estado_encomenda, valor
1758+ FROM encomendas
1759+ WHERE estado_encomenda = 'cancelado' OR valor > 25;
1760+
1761+ -- 17. Listar eventos privados e públicos (GROUP BY tipo evento)
1762+ SELECT evento_privado, COUNT(* ) AS total
1763+ FROM Eventos
1764+ GROUP BY evento_privado;
1765+
1766+ -- 18. Mostrar clientes sem data de nascimento (IS NULL)
1767+ SELECT id_cliente, nome
1768+ FROM Clientes
1769+ WHERE data_nascimento IS NULL;
1770+
1771+ -- 19. Produtos com designação distinta e preço superior a 4 EUR
1772+ SELECT DISTINCT designacao, preco_venda
1773+ FROM Produtos
1774+ WHERE preco_venda > 4;
1775+
1776+ -- 20. Listar clientes cujo email contém "gmail"
1777+ SELECT id_cliente, nome, email
1778+ FROM Clientes
1779+ WHERE email LIKE '%gmail%';
1780+
1781+ -- 21. Encomendas do fornecedor “SnackMasters Portugal”
1782+ SELECT id_encomenda, valor
1783+ FROM encomendas
1784+ WHERE id_fornecedor = (SELECT id_fornecedor FROM Fornecedores WHERE nome_empresa LIKE '%SnackMasters Portugal%');
1785+
1786+ -- 22. Clientes ordenados por data de modificação (ASC)
1787+ SELECT id_cliente, nome, data_modificacao
1788+ FROM Clientes
1789+ ORDER BY data_modificacao ASC;
1790+
1791+ -- 23. Produtos e stock atual, agrupados por tipo
1792+ SELECT tipo_de_produto, SUM(stock_atual) AS stock_total
1793+ FROM Produtos
1794+ GROUP BY tipo_de_produto;
1795+
1796+ -- 24. Pagamentos com moeda distinta (DISTINCT)
1797+ SELECT DISTINCT moeda
1798+ FROM Pagamentos;
1799+
1800+ -- 25. Funcionários que são “segurança” OU nasceram antes de 1985
1801+ SELECT id_funcionario, nome, funcao, data_nascimento
1802+ FROM Funcionarios
1803+ WHERE funcao = 'segurança' OR (data_nascimento IS NOT NULL AND data_nascimento < '1985-01-01');
1804+
1805+ -- 26. Produtos cujo preço de venda NÃO está entre 2 e 4 EUR
1806+ SELECT id_produto, designacao, preco_venda
1807+ FROM Produtos
1808+ WHERE NOT (preco_venda BETWEEN 2 AND 4);
1809+
1810+ -- 27. Avaliação dos clientes com nota máxima (5) e visíveis
1811+ SELECT id_cliente, avaliacao, comentario
1812+ FROM Avaliacao
1813+ WHERE avaliacao = 5 AND visibilidade;
1814+
1815+ -- 28. Pagamentos concluidos ordenados por valor, desc.
1816+ SELECT id_pagamento, valor, estado_pagamento
1817+ FROM Pagamentos
1818+ WHERE estado_pagamento = 'concluido'
1819+ ORDER BY valor DESC;
1820+
1821+ -- 29. Mostrar quantidade de participações em cada evento
1822+ SELECT id_evento, COUNT(* ) AS total_participantes
1823+ FROM Participacoes_Evento
1824+ GROUP BY id_evento
1825+ ORDER BY total_participantes DESC;
1826+
1827+ -- 30. Listar produtos com designações diferentes e ordenar de Z-A
1828+ SELECT DISTINCT designacao
1829+ FROM Produtos
1830+ ORDER BY designacao DESC;
1831+
1832+ SELECT
1833+ id_produto,
1834+ designacao,
1835+ stock_atual
1836+ FROM
1837+ Produtos
1838+ WHERE
1839+ tipo_de_produto = 'snacks'
1840+ AND stock_atual < 20;
1841+
1842+ SELECT
1843+ id_produto,
1844+ designacao,
1845+ preco_venda,
1846+ preco_compra,
1847+ (preco_venda - preco_compra) AS margem
1848+ FROM
1849+ Produtos
1850+ WHERE
1851+ preco_compra IS NOT NULL
1852+ ORDER BY
1853+ margem DESC
1854+ LIMIT 10;
1855+
1856+ SELECT f.id_funcionario, f.nome
1857+ FROM Funcionarios f
1858+ LEFT JOIN Pagamentos p ON f.id_funcionario = p.id_funcionario
1859+ WHERE p.id_pagamento IS NULL;
1860+
1861+ SELECT id_pagamento, id_cliente, valor
1862+ FROM Pagamentos
1863+ WHERE moeda = 'EUR' AND valor > 20;
1864+
1865+ SELECT id_produto, designacao,
1866+ preco_venda, preco_compra,
1867+ ROUND(((preco_venda - preco_compra) / preco_compra)* 100, 2) AS margem_percentual
1868+ FROM Produtos
1869+ WHERE preco_compra IS NOT NULL
1870+ ORDER BY margem_percentual DESC
1871+ LIMIT 10;
1872+
1873+ SELECT id_produto, designacao, preco_venda, stock_atual, stock_minimo
1874+ FROM Produtos
1875+ WHERE preco_venda > 2 AND stock_atual < stock_minimo;
1876+
1877+ SELECT id_fornecedor, nome_empresa, pais
1878+ FROM Fornecedores
1879+ WHERE NOT pais = 'Portugal';
1880+
1881+ SELECT id_evento, designacao, capacidade
1882+ FROM Eventos
1883+ WHERE capacidade BETWEEN 50 AND 100;
1884+
1885+ SELECT id_pagamento, valor, estado_pagamento
1886+ FROM Pagamentos
1887+ WHERE estado_pagamento IS 'pendente';
1888+
1889+ SELECT DISTINCT canal_aquisicao
1890+ FROM Clientes;
1891+
1892+ SELECT
1893+ moeda, -- Tipo de moeda usada no pagamento
1894+ COUNT(* ) AS total_pagamentos -- Contagem de pagamentos por moeda
1895+ FROM Pagamentos -- Origem dos dados
1896+ GROUP BY moeda -- Agrupa por moeda
1897+ HAVING COUNT(* ) < 5; -- Filtra apenas moedas com menos de 5 pagamentos
1898+
1899+ -- Listar fornecedores cujo nome inclua a palavra "brew", sem diferenciar maiúsculas de minúsculas
1900+ SELECT
1901+ id_fornecedor, -- ID do fornecedor
1902+ nome_empresa -- Nome da empresa fornecedora
1903+ FROM Fornecedores -- Origem dos fornecedores
1904+ WHERE nome_empresa ILIKE '%brew%'; -- Pesquisa sem considerar maiúsculas/minúsculas
1905+
1906+ -- Lista os clientes que fizeram mais do que 3 compras concluídas e quanto gastaram no total
1907+ SELECT
1908+ id_cliente, -- ID do cliente
1909+ COUNT(* ) AS total_compras, -- Nº total de compras
1910+ ROUND(SUM(valor), 2) AS total_gasto -- Soma do valor total gasto
1911+ FROM Pagamentos
1912+ WHERE estado_pagamento = 'concluido' -- Apenas compras concluídas
1913+ GROUP BY id_cliente -- Agrupar por cliente
1914+ HAVING COUNT(* ) > 1 -- Apenas quem comprou mais de 1 vez
1915+ ORDER BY total_compras DESC; -- Ordenar por quem mais comprou
1916+
1917+ -- Lista os produtos com preço de venda entre 5€ e 15€, ordenados do mais caro para o mais barato
1918+ SELECT
1919+ id_produto, -- ID do produto
1920+ designacao, -- Nome/designação do produto
1921+ preco_venda -- Preço de venda do produto
1922+ FROM Produtos -- Origem: tabela de produtos
1923+ WHERE preco_venda BETWEEN 2 AND 3 -- Apenas produtos cujo preço está entre 2 e 3 euros
1924+ ORDER BY preco_venda DESC; -- Ordena do preço mais alto para o mais baixo
1925+
1926+ ## 14. SQL Advanced Queries
1927+
1928+ -- Seleciona os 10 clientes com maior número de compras (visitas)
1929+ SELECT
1930+ c.id_cliente, -- ID do cliente
1931+ c.nome, -- Nome do cliente
1932+ COUNT(p.id_pagamento) AS frequencia_visitas -- Conta o nº total de pagamentos realizados
1933+ -- pelo cliente
1934+ FROM Clientes c -- Tabela principal: lista de todos os clientes
1935+ LEFT JOIN Pagamentos p -- Junta com pagamentos (LEFT JOIN para incluir clientes
1936+ -- sem compras)
1937+ ON c.id_cliente = p.id_cliente -- Relaciona clientes com pagamentos pelo id_cliente
1938+ GROUP BY c.id_cliente, c.nome -- Agrupa por cliente para contar o total de compras
1939+ ORDER BY frequencia_visitas DESC -- Ordena dos clientes mais frequentes para os menos
1940+ LIMIT 10; -- Mostra apenas os 10 primeiros resultados
1941+
1942+ -- Seleciona os 10 clientes que mais compram em média (em unidades de produto por compra)
1943+ SELECT
1944+ c.id_cliente, -- ID do cliente
1945+ c.nome, -- Nome do cliente
1946+ ROUND(AVG(qtd_por_compra), 2) AS volume_medio_consumo -- Média de unidades por compra
1947+ -- (arredondado a 2 casas decimais)
1948+ FROM (
1949+ -- Subconsulta para calcular a quantidade total de produtos por compra
1950+ SELECT
1951+ p.id_cliente, -- ID do cliente
1952+ SUM(ip.quantidade) AS qtd_por_compra -- Soma da quantidade de produtos comprados
1953+ -- nessa compra
1954+ FROM Pagamentos p
1955+ JOIN Itens_Pagamento ip
1956+ ON p.id_pagamento = ip.id_pagamento -- Liga pagamento com os seus itens
1957+ GROUP BY p.id_pagamento, p.id_cliente -- Agrupa por compra para calcular total de unidades
1958+ -- por transação
1959+ ) sub
1960+ JOIN Clientes c ON c.id_cliente = sub.id_cliente -- Junta com a tabela de clientes para trazer
1961+ -- os nomes
1962+ GROUP BY c.id_cliente, c.nome -- Agrupa novamente para calcular a média por cliente
1963+ ORDER BY volume_medio_consumo DESC -- Ordena dos que mais consomem para menos
1964+ LIMIT 10; -- Mostra apenas os 10 primeiros resultados
1965+
1966+ -- Seleciona os 10 clientes cuja última compra foi mais recente
1967+ SELECT
1968+ c.id_cliente, -- ID do cliente
1969+ c.nome, -- Nome do cliente
1970+ MAX(p.data_pagamento) AS ultima_compra -- Obtém a data mais recente de pagamento
1971+ FROM Clientes c
1972+ LEFT JOIN Pagamentos p
1973+ ON c.id_cliente = p.id_cliente -- Liga com a tabela de pagamentos
1974+ GROUP BY c.id_cliente, c.nome -- Agrupa por cliente
1975+ ORDER BY ultima_compra DESC -- Ordena da compra mais recente para a mais antiga
1976+ LIMIT 10; -- Mostra apenas os 10 primeiros resultados
1977+
1978+ -- Seleciona os 10 clientes que mais gastaram no total (€)
1979+ SELECT
1980+ c.id_cliente, -- ID do cliente
1981+ c.nome, -- Nome do cliente
1982+ ROUND(SUM(p.valor), 2) AS total_gasto -- Soma do valor total gasto (apenas compras concluídas)
1983+ FROM Clientes c
1984+ LEFT JOIN Pagamentos p
1985+ ON c.id_cliente = p.id_cliente
1986+ AND p.estado_pagamento = 'concluido' -- Filtra apenas pagamentos concluídos
1987+ GROUP BY c.id_cliente, c.nome -- Agrupa por cliente
1988+ ORDER BY total_gasto DESC -- Ordena do maior para o menor gasto
1989+ LIMIT 10; -- Mostra apenas os 10 primeiros resultados
1990+
1991+ -- Seleciona os 10 clientes com maior ticket médio por compra
1992+ SELECT
1993+ c.id_cliente, -- ID do cliente
1994+ c.nome, -- Nome do cliente
1995+ ROUND(AVG(p.valor), 2) AS media_consumo_compra -- Calcula o valor médio gasto por compra
1996+ FROM Clientes c
1997+ LEFT JOIN Pagamentos p
1998+ ON c.id_cliente = p.id_cliente
1999+ AND p.estado_pagamento = 'concluido' -- Apenas compras concluídas
2000+ GROUP BY c.id_cliente, c.nome -- Agrupa por cliente
2001+ ORDER BY media_consumo_compra DESC -- Ordena do maior valor médio para o menor
2002+ LIMIT 10; -- Mostra apenas os 10 primeiros resultados
0 commit comments