22nd Jan 2025 15 minutos de leitura Exercícios de SQL para o banco de dados Northwind Maria Durkin práticas sql Índice Visão geral do banco de dados Northwind Exercícios do banco de dados Northwind 1. Consultas de tabela única Exercício 1: Todos os produtos Exercício 2: Produtos mais caros do que 3,5 Exercício 3: Nomes e e-mails de clientes 2. Consultas de várias tabelas Exercício 4: Produto e categorias Exercício 5: Funcionários e compras, parte 1 Exercício 6: Funcionários e compras, parte 2 3. ORDER BY: Classificando seus resultados Exercício 7: Funcionários por data de nascimento Exercício 8: Nomes e preços dos produtos Exercício 9: Dados de compra 4. Funções GROUP BY e Aggregate Exercício 10: Número de categorias Exercício 11: Compras de clientes Exercício 12: Receita para pares de clientes e funcionários 5. Outros recursos SQL Exercício 13: Data de contratação desconhecida Exercício 14: Preço médio por categoria 6. SQL Avançado Recursos Exercício 15: Categorias com produtos ativos Exercício 16: Estatísticas de vinhos Quer mais exercícios da Northwind para alunos de SQL? Quando se trata de aprender SQL, muitos iniciantes têm dificuldade em adquirir experiência prática que possa se traduzir em cenários do mundo real. Enfrentaremos esse desafio apresentando exercícios de SQL do banco de dados Northwind com soluções e explicações. Neste artigo, abordaremos 16 exercícios da Northwind extraídos do nosso curso prático de SQL Basic Trilha de Práticas em SQL: A Store. Como você deve ter adivinhado, o curso usa o clássico banco de dados Northwind da Microsoft. Trata-se de um banco de dados de uma pequena empresa comercial, projetado para oferecer aos alunos de SQL alguma experiência prática. Ele inclui dados realistas de clientes, produtos, fornecedores e pedidos, o que o torna um ponto de partida ideal para aqueles que desejam desenvolver habilidades básicas de SQL. Cada vez mais dados são gerados diariamente, o que torna os bancos de dados essenciais para o armazenamento seguro e organizado de informações. Usando SQL, ou Structured Query Language (Linguagem de Consulta Estruturada), podemos extrair insights dos dados contidos nesses bancos de dados. O SQL nos permite extrair, analisar e manipular dados para nossa análise. Embora o aprendizado de SQL possa parecer desafiador no início, a proficiência aumenta com a prática, assim como o aprendizado de qualquer idioma. O próprio curso Basic Trilha de Práticas em SQL: A Store oferece 169 exercícios interativos que abrangem uma ampla gama de tópicos de SQL. Para nos familiarizarmos com o tipo de conteúdo do curso, examinaremos as perguntas de cada área. Esses exercícios o ajudarão a aprimorar suas habilidades e confiança em SQL. Visão geral do banco de dados Northwind Vamos começar dando uma olhada no banco de dados que usaremos: Cada uma das tabelas desse banco de dados representa um objeto exclusivo e está vinculada a outras tabelas por meio de chaves primárias e estrangeiras. A chave primária identifica de forma exclusiva cada registro em uma tabela (por exemplo, customer_id na tabela Customer ), o que nos permite conectar tabelas e obter dados relevantes criando uma ponte entre elas. Vamos dar uma breve olhada em cada tabela: employee: Essa tabela contém dados sobre os funcionários da empresa, o que pode ser útil para análises de RH e de desempenho dos funcionários. purchase: Essa tabela contém dados de transações entre clientes e a empresa. Essas informações podem ajudar na análise de compras, no planejamento de estoque e na análise de localização. customer: Dados de clientes: Essa tabela contém dados sobre os clientes da empresa. Isso pode ser útil para identificar públicos-alvo e personalizar serviços. purchase_item: Essa tabela conecta as compras aos produtos e nos permite obter informações sobre os preços e as quantidades dos diferentes produtos em cada pedido. product: Essa tabela exibe dados sobre os produtos da oferta da empresa. Isso pode fornecer insights sobre produtos populares e seus detalhes. category: Essa tabela contém informações sobre diferentes categorias de produtos, o que pode ajudar a obter informações sobre categorias populares. Exercícios do banco de dados Northwind Agora vamos nos aprofundar em alguns exercícios práticos de SQL baseados nesse banco de dados. Vamos dividir este artigo em seis seções, cada uma introduzindo diferentes habilidades de SQL. Mantenha nossa Folha de consulta de SQL por perto para ter uma referência rápida sobre as funções e a sintaxe que usaremos. 1. Consultas de tabela única Para começar, vamos começar com o básico: filtrar e recuperar dados de uma única tabela. Nesses exercícios, você usará as cláusulas SELECT e WHERE para extrair informações específicas de tabelas individuais. O domínio desses comandos SQL essenciais estabelecerá uma base sólida para a criação de consultas mais complexas posteriormente. Exercício 1: Todos os produtos Exiba todos os dados presentes na tabela product tabela. Solução: SELECT * FROM product; Explicação: Nessa consulta: SELECT * instrui o SQL a selecionar todas as colunas da tabela product FROM product especifica a tabela que estamos usando. Essa consulta retorna todas as linhas e colunas da tabela product fornecendo uma visão completa dos detalhes de cada produto no banco de dados. Exercício 2: Produtos mais caros do que 3,5 Exiba os nomes dos produtos com um preço unitário maior ou igual a 3,5. Solução: SELECT product_name FROM product WHERE unit_price >= 3.5; Explicação: Nessa consulta: SELECT product_name especifica que queremos apenas os nomes dos produtos. FROM product especifica a tabela que está sendo usada. WHERE unit_price >= 5 limita a saída aos produtos com preço igual ou superior a 3,5. Essa consulta é útil para identificar os itens mais caros da loja. Exercício 3: Nomes e e-mails de clientes Exiba os nomes e os e-mails dos clientes. Você encontrará o nome na coluna contact_name e o e-mail na coluna contact_email da tabela customer tabela. Renomeie as colunas para name e email, respectivamente. Solução: SELECT contact_name AS name, contact_email AS email FROM customer; Explicação: Nessa consulta: SELECT contact_name AS name pega a coluna contact_name e a renomeia na saída como name. A mesma coisa é feita com contact_email AS email. FROM customer especifica a tabela que estamos usando. O aliasing com AS torna os resultados mais legíveis e fáceis de usar. Isso pode ser especialmente útil ao compartilhar resultados com partes interessadas não técnicas. Você pode encontrar mais exemplos de exercícios práticos e simples em nosso artigo Trilha de Práticas em SQL para iniciantes: Exercícios do AdventureWorks. 2. Consultas de várias tabelas Esta seção se concentra na combinação de dados de diferentes tabelas usando JOINs; isso nos permite criar consultas mais complexas. Exercício 4: Produto e categorias Selecione os nomes dos produtos junto com suas categorias. Exiba duas colunas: product_name e category_name. Solução: SELECT product_name, category.name AS category_name FROM product JOIN category ON product.category_id = category.category_id; Explicação: Nessa consulta: SELECT product_name, category.name AS category_name identifica as colunas que são solicitadas em nosso resultado. FROM product especifica a primeira tabela em nosso site JOIN. JOIN category especifica a segunda tabela em nosso site JOIN. ON product.category_id = category.category_id atua como uma ponte entre as duas tabelas e garante que somente as linhas com IDs de categoria correspondentes sejam incluídas no conjunto de resultados. Exercício 5: Funcionários e compras, parte 1 Mostre o sobrenome e o nome dos funcionários que estão lidando com as compras, juntamente com o endereço shipped_date da compra. Solução: SELECT last_name, first_name, shipped_date FROM employee JOIN purchase ON employee.employee_id = purchase.employee_id; Explicação: Nessa consulta: SELECT last_name, first_name, shipped_date identifica as colunas que são mostradas em nosso resultado. FROM employee indica a primeira tabela em nosso JOIN. JOIN purchase especifica a segunda tabela em nosso JOIN. ON employee.employee_id = purchase.employee_id junta as duas tabelas nas linhas em que o ID do funcionário na tabela employee corresponde ao ID do funcionário na tabela purchase Somente as linhas com IDs correspondentes são incluídas no conjunto de resultados. Exercício 6: Funcionários e compras, parte 2 Para cada funcionário, exiba os endereços last_name, first_name e o ID da(s) compra(s) com a(s) qual(is) ele lidou (se houver). Certifique-se de exibir os dados de todos os funcionários, mesmo que eles não tenham se envolvido com nenhuma compra. Solução: SELECT last_name, first_name, purchase_id FROM employee LEFT JOIN purchase ON employee.employee_id = purchase.employee_id; Explicação: Nessa consulta: SELECT last_name, first_name, purchase_id especifica as colunas a serem incluídas na saída. FROM employee designa a primeira tabela em nosso site LEFT JOIN, que contém detalhes sobre os funcionários. LEFT JOIN purchase especifica a segunda tabela na união, que contém dados sobre compras. O uso de LEFT JOIN garante que todas as linhas da tabela employee sejam incluídas, mesmo que não haja nenhum registro correspondente na tabela purchase. purchase ON employee.employee_id = purchase.employee_id conecta as duas tabelas, combinando registros com base no ID do funcionário. Se um funcionário não tiver um registro correspondente na tabela purchase ele ainda será incluído no resultado e os campos de compra no conjunto de resultados serão exibidos como NULL. Como você pode ver, escrever consultas realmente desenvolve suas habilidades em SQL! Outra ótima maneira de desenvolver suas habilidades em SQL é por meio de projetos como os do SQL Project for Beginners: AdventureWorks Sales Dashboard (Painel de vendas do AdventureWorks). 3. ORDER BY: Classificando seus resultados A cláusula ORDER BY no SQL é particularmente útil para organizar os resultados de forma mais legível e significativa. Se você quiser classificar os dados numericamente, alfabeticamente ou por data, isso é muito útil em relatórios e análises. Exercício 7: Funcionários por data de nascimento Mostre os sobrenomes, os nomes e as datas de nascimento dos funcionários. Classifique os funcionários por data de nascimento em ordem decrescente (ou seja, as datas mais recentes vêm primeiro). Solução: SELECT last_name, first_name, birth_date FROM employee ORDER BY birth_date DESC; Explicação: Nessa consulta: SELECT last_name, first_name, birth_date especifica as colunas a serem incluídas na saída. FROM employee indica a tabela da qual os dados são recuperados. ORDER BY birth_date DESC classifica os resultados pela coluna birth_date em ordem decrescente, de modo que os funcionários com as datas de nascimento mais recentes apareçam primeiro. Isso supera a limitação de não ter uma coluna de idade. Exercício 8: Nomes e preços dos produtos Exiba os nomes e os preços unitários de todos os produtos. Mostre os produtos mais baratos primeiro. Solução: SELECT product_name, unit_price FROM product ORDER BY unit_price; Explicação: Nessa consulta: SELECT product_name, unit_price especifica as colunas a serem incluídas na saída. FROM product identifica a tabela da qual os dados são extraídos. ORDER BY unit_price classifica os resultados pela coluna unit_price em ordem crescente, o que significa que os produtos com os preços mais baixos aparecerão primeiro. Como você pode ver, não é necessário especificar explicitamente ASCending; essa é a ordem de classificação padrão. Exercício 9: Dados de compra Mostre todos os dados de todas as compras. Classifique as linhas pela cidade de envio em ordem crescente e pela data de envio em ordem decrescente. Solução: SELECT * FROM purchase ORDER BY ship_city ASC, shipped_date DESC; Explicação: Nessa consulta: SELECT * especifica que todas as colunas da tabela devem ser incluídas na saída. FROM purchase identifica a tabela da qual os dados são recuperados. ORDER BY ship_city ASC, shipped_date DESC classifica os resultados primeiro por ship_city em ordem crescente (para que as cidades sejam classificadas em ordem alfabética). Em seguida, dentro de cada cidade, os resultados são classificados por shipped_date em ordem decrescente (para que as datas de remessa mais recentes apareçam primeiro para cada cidade). Se quiser encontrar mais exercícios com ORDER BY, confira nosso artigo 10 exercícios para iniciantes em Trilha de Práticas em SQL com soluções. 4. Funções GROUP BY e Aggregate A próxima seção ajuda a desenvolver a habilidade de resumir dados por meio de agrupamento e agregação. Usando funções de agregação, podemos obter insights combinando linhas e realizando cálculos dentro de cada grupo. Exercício 10: Número de categorias Conte o número de categorias presentes na tabela category tabela. Nomeie a coluna number_of_categories. Solução: SELECT COUNT(category_id) AS number_of_categories FROM category; Explicação: Nessa consulta: SELECT COUNT(category_id) AS number_of_categories conta o número de linhas que não têm NULLs no category_id. Exibe a coluna resultante como number_of_categories. FROM category especifica a tabela da qual os dados são recuperados. Exercício 11: Compras de clientes Conte o número de compras feitas por cada cliente. Exiba as colunas customer_id, contact_name e purchases_number. Ignore os clientes que não estiverem presentes na tabela. purchase tabela. Solução: SELECT purchase.customer_id, contact_name, COUNT(*) AS purchases_number FROM purchase JOIN customer ON purchase.customer_id = customer.customer_id GROUP BY purchase.customer_id, contact_name; Explicação: Nessa consulta: SELECT purchase.customer_id, contact_name, COUNT(*) AS purchases_number especifica as colunas a serem incluídas na saída. Ela recupera o ID e o nome de contato de cada cliente, juntamente com a contagem de suas compras (rotulada como purchases_number). FROM purchase identifica a primeira tabela em JOIN. JOIN customer especifica a segunda tabela em JOIN. ON purchase.customer_id = customer.customer_id vincula as duas tabelas, combinando as linhas em que o customer_id é o mesmo em ambas as tabelas e garantindo que somente as compras associadas aos clientes existentes sejam incluídas. GROUP BY purchase.customer_id, contact_name agrupa os resultados por ID e nome de contato de cada cliente, permitindo que a função COUNT(*) calcule o número de compras de cada cliente. Exercício 12: Receita para pares de clientes e funcionários Para cada cliente e funcionário, encontre o preço total de todas as compras que eles fizeram às quais um determinado funcionário está atribuído. Exiba três colunas: customer_id, employee_id, e o preço total das compras. Renomeie a terceira coluna para total_purchases_price. Solução: SELECT customer_id, employee_id, SUM(total_price) AS total_purchases_price FROM purchase GROUP BY customer_id, employee_id; Explicação: Nessa consulta: SELECT customer_id, employee_id, SUM(total_price) AS total_purchases_price especifica as colunas a serem incluídas no resultado, mostrando cada customer_id e employee_id junto com a soma de total_price para compras associadas a cada combinação. Essa soma é rotulada como total_purchases_price no resultado. FROM purchase identifica a tabela da qual os dados são extraídos. GROUP BY customer_id, employee_id agrupa os resultados por customer_id e employee_id, permitindo que a função SUM(total_price) calcule o preço total de compra para cada combinação exclusiva de cliente e funcionário. 5. Outros recursos SQL A seguir, abordaremos brevemente mais alguns recursos SQL que estão incluídos no curso, mas que também são úteis na análise cotidiana. Essas funções, quando combinadas com outras discutidas neste artigo, podem ajudá-lo a aprimorar suas habilidades em SQL. Exercício 13: Data de contratação desconhecida Exibir o sobrenome e o nome dos funcionários com data de contratação desconhecida. Solução: SELECT last_name, first_name FROM employee WHERE hire_date IS NULL; Explicação: Nessa consulta: SELECT last_name, first_name especifica as colunas a serem incluídas na saída. FROM employee indica a tabela da qual os dados são extraídos. WHERE hire_date IS NULL filtra os resultados para incluir somente os funcionários cujo endereço hire_date é NULL, o que significa que a data de contratação é desconhecida. Exercício 14: Preço médio por categoria Para cada categoria, conte o preço médio de seus produtos. Exiba somente as categorias para as quais o preço unitário médio é maior que o preço unitário médio geral. Nomeie as colunas category_name e average_price. Solução: SELECT category.name AS category_name, AVG(unit_price) AS average_price FROM product JOIN category ON product.category_id = category.category_id GROUP BY category.name HAVING AVG(unit_price) > ( SELECT AVG(unit_price) FROM product ); Explicação: Nessa consulta: SELECT category.name AS category_name, AVG(unit_price) AS average_price especifica as colunas a serem incluídas na saída. FROM product identifica a primeira tabela em JOIN. JOIN category especifica a segunda tabela no site JOIN. ON product.category_id = category.category_id vincula as duas tabelas, garantindo que somente os produtos com IDs de categoria correspondentes de ambas as tabelas sejam incluídos. GROUP BY category.name agrupa os resultados por nome de categoria, permitindo que a função AVG(unit_price) calcule o preço médio de cada categoria. HAVING AVG(unit_price) > (SELECT AVG(unit_price) FROM product) filtra os resultados agrupados para incluir somente as categorias em que o preço médio dos produtos é maior do que o preço médio geral de todos os produtos na tabela de categorias. product A subconsulta (SELECT AVG(unit_price) FROM product) calcula a média geral do preço unitário de todos os produtos. 6. SQL Avançado Recursos Por fim, examinaremos algumas consultas SQL mais avançadas. Ao fazermos isso, faremos referência às funções que vimos anteriormente. Exercício 15: Categorias com produtos ativos Para cada categoria, exiba o número de seus produtos que não foram descontinuados (eles continuam ou há um NULL na coluna discontinued ). Mostre as colunas denominadas category_name e products_number. Mostre somente as linhas para as quais o número de tais produtos é maior que 1. Além disso, não mostre a linha para a categoria Other. Solução: SELECT category.name AS category_name, COUNT(product_id) AS products_number FROM product JOIN category ON product.category_id = category.category_id WHERE category.name <> 'Other' AND discontinued IS NOT TRUE GROUP BY category.name HAVING COUNT(product_id) > 1; Explicação: Nessa consulta: SELECT category.name AS category_name, COUNT(product_id) AS products_number especifica as colunas a serem incluídas na saída. FROM product identifica a primeira tabela em JOIN. JOIN category especifica a segunda tabela no site JOIN. ON product.category_id = category.category_id vincula as duas tabelas, garantindo que apenas os produtos com IDs de categoria correspondentes de ambas as tabelas sejam incluídos. WHERE category.name <> 'Other' AND discontinued IS NOT TRUE filtra os resultados para excluir as categorias denominadas "Other" e para incluir apenas produtos que não foram descontinuados. GROUP BY category.name agrupa os resultados por nome de categoria, permitindo que a função COUNT(product_id) conte o número de produtos em cada categoria. HAVING COUNT(product_id) > 1 filtra os resultados agrupados para incluir somente categorias com mais de um produto. Exercício 16: Estatísticas de vinhos Todos os vinhos na tabela de produtos têm um nome que começa com Wine. Encontre o: Número de produtos desse tipo na tabela (products_number). Número total de unidades em estoque (units_number). Preço médio do produto (average_price). Razão entre o preço máximo e o preço mínimo (max_to_min_ratio). Diferença entre o preço máximo e o preço médio (max_to_average). Diferença entre o preço médio e o preço mínimo (average_to_min). Arredonde as quatro últimas colunas para duas casas decimais. Solução: SELECT COUNT(*) AS products_number, SUM(units_in_stock) AS units_number, ROUND(AVG(unit_price), 2) AS average_price, ROUND(MAX(unit_price) / MIN(unit_price), 2) AS max_to_min_ratio, ROUND(MAX(unit_price) - AVG(unit_price), 2) AS max_to_average, ROUND(AVG(unit_price) - MIN(unit_price), 2) AS average_to_min FROM product WHERE product_name LIKE 'Wine%'; Explicação: Nessa consulta: Primeiro, vamos decompor a declaração SELECT: products_number calcula o número total de produtos. units_number soma o número total de unidades em estoque. average_price obtém o preço unitário médio dos produtos, arredondado para 2 casas decimais. max_to_min_ratio encontra a razão entre o preço unitário máximo e o preço unitário mínimo, arredondado para 2 casas decimais. max_to_average encontra a diferença entre o preço unitário máximo e o preço unitário médio, arredondado para 2 casas decimais. average_to_min calcula a diferença entre o preço unitário médio e o preço unitário mínimo, com arredondamento de 2 casas decimais. FROM product identifica a tabela da qual os dados foram extraídos. WHERE product_name LIKE 'Wine%' filtra os resultados para incluir somente os produtos cujos nomes começam com 'Wine'. Quer mais exercícios da Northwind para alunos de SQL? Ao praticar a elaboração de consultas, você pode fortalecer suas habilidades em SQL. Trabalhar com dados do mundo real, como o banco de dados Northwind, dá a você experiência em acessar e avaliar informações rapidamente. Se você achou os exercícios do Northwind deste artigo interessantes, não deixe de conferir o curso Basic Trilha de Práticas em SQL: A Store. Você encontrará muitos outros exercícios interativos. Também temos o SQL Project for Portfolio: Northwind Store, um artigo sobre a criação de um projeto baseado no banco de dados Northwind. Bom aprendizado! Tags: práticas sql