@@ -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