Voltar para a lista de artigos Artigos
18 minutos de leitura

Prática de SQL para iniciantes: Exercícios do AdventureWorks

Índice

Aprimore suas habilidades em SQL com exercícios práticos usando o banco de dados de amostra do AdventureWorks. Pratique os recursos essenciais do SQL usando cenários do mundo real.

Praticar o SQL é importante se você quiser melhorar seu uso. Este artigo apresenta 20 exercícios para iniciantes usando o banco de dados de amostra AdventureWorks da Microsoft. Esse banco de dados foi projetado para mostrar como o SQL Server funciona. Ele representa uma empresa fictícia de fabricação de bicicletas chamada AdventureWorks Cycles e inclui cinco esquemas: HumanResources (Recursos Humanos), Person (Pessoas), Production (Produção), Purchasing (Compras) e Sales (Vendas). Isso o torna excelente para o aprendizado e a prática de SQL.

O banco de dados da AdventureWorks abrange vários cenários de negócios, como fabricação, vendas, compras, gerenciamento de produtos, gerenciamento de contatos e recursos humanos. Isso o torna um excelente recurso para aprender e praticar SQL, pois oferece uma ampla gama de dados e processos de negócios com os quais trabalhar. Ao praticar com esse banco de dados, você pode ganhar experiência prática com dados e cenários do mundo real; isso o ajudará a entender como escrever consultas eficientes e resolver problemas de dados com eficácia.

Se você quiser experimentar outros bancos de dados de amostra, confira nossa lista das fontes de dados mais interessantes para a prática de SQL. No entanto, a configuração de seu próprio ambiente de prática de SQL pode levar tempo. Para praticar rapidamente, experimente nossa trilhaTrilha de Práticas em SQL ou nossos bancos de dados de prática de SQL. Também lançamos um curso gratuito de SQL por mês para ajudá-lo a continuar aprendendo.

Agora, vamos começar a praticar SQL com os exercícios do AdventureWorks!

Revisão do banco de dados do AdventureWorks

O banco de dados AdventureWorks é composto por cinco esquemas de banco de dados (ou seja, estruturas de banco de dados usadas para agrupar tabelas de dados), incluindo HumanResources, Person, Production, Purchasing e Sales. Nos exercícios a seguir, usaremos o esquema HumanResources.

Vamos começar analisando o esquema:

Banco de dados AdventureWorks

Primeiro, vamos revisar os conceitos de chaves primárias e estrangeiras:

  • A chave primária (PK) é uma coluna (ou um conjunto de colunas) que identifica exclusivamente cada linha em uma tabela. Por exemplo, a coluna BusinessEntityID é a chave primária da tabela Employee porque cada funcionário recebe um número de identificação exclusivo.
  • A chave estrangeira (FK) é uma coluna (ou um conjunto de colunas) que vincula duas tabelas. Observe que a chave estrangeira de uma tabela é a chave primária de outra tabela - com base nisso, as duas tabelas são vinculadas. Por exemplo, a coluna BusinessEntityID é a chave primária da tabela Employee e também uma chave estrangeira na tabela JobCandidate da tabela. Isso vincula as duas tabelas e permite que a tabela JobCandidate faça referência a linhas na tabela Employee

Agora, vamos analisar as tabelas no esquema.

A tabela Employee armazena informações sobre os funcionários e é a tabela principal desse esquema. Ela está vinculada às seguintes tabelas:

  • A tabela JobCandidate armazena os currículos dos candidatos a emprego. A coluna BusinessEntityID é um PK na tabela Employee e uma FK na tabela JobCandidate O PK da tabela JobCandidate da tabela é a coluna JobCandidateID.
  • A tabela EmployeePayHistory tabela armazena o histórico das taxas de pagamento dos funcionários. A coluna BusinessEntityID é um PK na tabela Employee e uma FK na tabela EmployeePayHistory Observe que a coluna BusinessEntityID na tabela EmployeePayHistory é uma FK e parte da PK ao mesmo tempo. O PK da tabela EmployeePayHistory da tabela compreende as colunas BusinessEntityID e RateChangeDate. Isso é chamado de chave primária composta.
  • A tabela EmployeeDepartmentHistory A tabela armazena o histórico dos departamentos dos funcionários. A coluna BusinessEntityID é uma PK na tabela Employee e uma FK na tabela EmployeeDepartmentHistory Observe que a coluna BusinessEntityID na tabela EmployeeDepartmentHistory é uma FK e parte da PK ao mesmo tempo. O PK da tabela EmployeeDepartmentHistory da tabela compreende as colunas BusinessEntityID, DepartmentID, ShiftID e StartDate. Essa é outra chave primária composta.

A tabela EmployeeDepartmentHistory armazena informações sobre os funcionários e seus departamentos ao longo do tempo e pode ser considerada outra tabela principal desse esquema. Ela está vinculada às tabelas a seguir:

  • A tabela Shift armazena informações sobre os turnos disponíveis. A coluna ShiftID é um PK na tabela Shift e uma FK na tabela EmployeeDepartmentHistory Observe que a coluna ShiftID é um FK e parte do PK na tabela EmployeeDepartmentHistory tabela.
  • A tabela Department armazena informações sobre departamentos. A coluna DepartmentID é um PK na tabela Department e uma FK na tabela EmployeeDepartmentHistory Observe que a coluna DepartmentID é uma FK e parte da PK na tabela EmployeeDepartmentHistory tabela.

Agora estamos prontos para começar nossos exercícios do AdventureWorks.

Exercícios do AdventureWorks para iniciantes

Cobriremos todos os conceitos básicos de SQL (e alguns recursos avançados) à medida que avançarmos neste artigo:

  • Consultas de tabela única para recuperação e filtragem de dados.
  • Consultas em várias tabelas que usam JOINs para combinar dados de duas ou mais tabelas.
  • Agrupamento e agregação de dados para realizar operações matemáticas nos dados selecionados.
  • Outros recursos SQL relevantes, como subconsultas, UNION e INTERSECT, e expressões de tabela comuns (CTEs).

Parte 1: Consultas de tabela única

Nesta parte, recuperaremos e filtraremos dados.

Observação: para escrever consultas corretas, você deve primeiro se familiarizar com os dados armazenados nas tabelas.

Exercício 1: Selecionar os cargos de todos os funcionários solteiros do sexo masculino

Exercício: Selecione o cargo de todos os funcionários do sexo masculino que não são casados.

Solução:

SELECT JobTitle
FROM HumanResources.Employee
WHERE Gender = 'M'
AND MaritalStatus != 'M';

Explicação: Selecionamos a coluna JobTitle da tabela Employee da tabela. Aqui, a sintaxe SQL pode ser lida exatamente como em inglês simples.

As condições de filtragem são colocadas na cláusula WHERE:

  • Queremos selecionar somente funcionários do sexo masculino, portanto, impomos uma condição na coluna Gender: Gender = 'M'.
  • Queremos selecionar somente os funcionários que não são casados, portanto, impomos outra condição na coluna MaritalStatus: MaritalStatus != 'M'.

Como ambas as condições devem ser aplicadas ao mesmo tempo, usamos o operador AND para combiná-las.

Exercício 2: Selecionar funcionários cuja taxa de pagamento seja 50 ou mais

Exercício: Selecione as colunas BusinessEntityID, Rate e RateChangeDate para todos os funcionários cuja taxa de pagamento já foi de 50 ou mais.

Solução:

SELECT BusinessEntityID, Rate, RateChangeDate
FROM HumanResources.EmployeePayHistory
WHERE Rate >= 50;

Explicação: Selecionamos três colunas - BusinessEntityID, Rate e RateChangeDate - da tabela. EmployeePayHistory tabela.

Em seguida, fornecemos uma condição de filtragem na cláusula WHERE para recuperar somente aqueles cuja taxa de pagamento já foi maior ou igual a 50: Rate >= 50.

Exercício 3: Selecionar todos os funcionários que ingressaram em novos departamentos em 2008

Exercício: Selecione os endereços BusinessEntityID, DepartmentID e StartDate para cada funcionário que começou a trabalhar em qualquer departamento em 2008.

Solução:

SELECT BusinessEntityID, DepartmentID, StartDate
FROM HumanResources.EmployeeDepartmentHistory
WHERE StartDate BETWEEN '2008-01-01' AND '2008-12-31';

Explicação: Selecionamos os IDs dos funcionários (BusinessEntityID), os IDs dos departamentos (DepartmentID) e a data em que o funcionário ingressou no departamento (StartDate) na tabela EmployeeDepartmentHistory tabela.

Como queremos listar somente os funcionários que ingressaram em novos departamentos em 2008, impomos uma condição na coluna StartDate: StartDate BETWEEN '2008-01-01' AND '2008-12-31'.

Essa condição é autoexplicativa, pois é compreensível em inglês simples. Queremos que o valor StartDate esteja entre 1º de janeiro de 2008 e 31 de dezembro de 2008, garantindo a cobertura de todos os dias de 2008.

Exercício 4: Selecionar departamentos cujos nomes correspondam ao padrão

Exercício: Selecione os IDs de departamento, os nomes e os nomes de grupo de todos os departamentos cujo nome comece com "Prod" OU de todos os departamentos cujo nome de grupo termine com "ring".

Solução:

SELECT DepartmentID, Name, GroupName
FROM HumanResources.Department
WHERE Name LIKE 'Prod%'
OR GroupName LIKE '%ring';

Explicação: Selecionamos as colunas DepartmentID, Name e GroupName da tabela. Department da tabela.

Em seguida, fornecemos as condições da cláusula WHERE:

  • Queremos selecionar os departamentos cujo nome começa com "Prod", portanto, impomos uma condição à coluna Name: Name LIKE 'Prod%'.
  • Também queremos selecionar os departamentos cujo nome do grupo termina com "ring", portanto, impomos uma condição na coluna GroupName: GroupName LIKE '%ring'.

A palavra-chave LIKE nos permite definir o padrão ao qual o valor da coluna deve corresponder. Por exemplo, queremos que a coluna Name comece com "Prod", portanto o padrão é 'Prod%'; % representa qualquer sequência de caracteres.

Como queremos encontrar todos os registros em que pelo menos uma das condições seja verdadeira, usamos a palavra-chave OR.

Exercício 5: Selecionar departamentos que pertencem a determinados grupos

Exercício: Selecione os nomes de departamentos que pertencem ao grupo "Pesquisa e desenvolvimento" ou ao grupo "Manufatura".

Solução:

SELECT Name
FROM HumanResources.Department
WHERE GroupName IN ('Research and Development', 'Manufacturing');

Explicação: Selecionamos a coluna Name da tabela Department tabela.

Como queremos listar os departamentos que pertencem a grupos definidos, usamos a palavra-chave IN na condição da cláusula WHERE: GroupName IN ('Research and Development', 'Manufacturing').

Isso garante a saída de todos os departamentos que pertencem aos grupos listados na palavra-chave IN.

Parte 2: Consultas em várias tabelas

Nesta parte, usaremos JOINs para combinar dados de várias tabelas.

Observação: para escrever consultas corretas, você deve primeiro se familiarizar com os dados armazenados nas tabelas relevantes.

Exercício 6: Selecionar funcionários e seus departamentos

Exercício: Selecione os IDs dos funcionários com todos os nomes dos departamentos em que eles já trabalharam.

Solução:

SELECT edh.BusinessEntityID, d.Name
FROM HumanResources.EmployeeDepartmentHistory AS edh
JOIN HumanResources.Department AS d
ON edh.DepartmentID = d.DepartmentID;

Explicação: Selecionamos a coluna BusinessEntityID da tabela EmployeeDepartmentHistory e a coluna Name da tabela Department tabela.

Unimos essas duas tabelas usando a cláusula JOIN em sua coluna comum, DepartmentID.

Exercício 7: Selecionar os cargos e as datas de mudança de departamento das funcionárias

Exercício: Selecione o ID do funcionário e o cargo junto com as datas em que o funcionário mudou de departamento (StartDate) para todas as funcionárias.

Solução:

SELECT e.BusinessEntityID, e.JobTitle, edh.StartDate
FROM HumanResources.Employee AS e
JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.BusinessEntityID = edh.BusinessEntityID
WHERE e.Gender = 'F';

Explicação: Selecionamos as colunas BusinessEntityID e JobTitle da tabela Employee e a coluna StartDate da tabela EmployeeDepartmentHistory tabela.

Usamos a cláusula JOIN para unir as tabelas em sua coluna comum, BusinessEntityID.

Como queremos listar essas informações somente para funcionários do sexo feminino, impomos uma condição na coluna Gender: e.Gender = 'F'.

Exercício 8: Selecionar títulos de cargos por departamento

Exercício: Selecione os títulos dos cargos e os nomes dos departamentos correspondentes para encontrar todos os títulos de cargos que já foram usados em cada departamento. Não inclua múltiplos do mesmo cargo.

Solução:

SELECT DISTINCT e.JobTitle, d.Name
FROM HumanResources.Employee AS e
JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.BusinessEntityID = edh.BusinessEntityID
JOIN HumanResources.Department AS d
ON edh.DepartmentID = d.DepartmentID;

Explicação: Selecionamos a coluna JobTitle da tabela Employee e a coluna Name da tabela Department tabela.

Para selecionar títulos de cargos distintos (ou seja, sem duplicatas), usamos a palavra-chave DISTINCT antes dos nomes das colunas.

Devemos unir a tabela Employee com a tabela EmployeeDepartmentHistory em sua coluna comum, BusinessEntityID. Em seguida, juntamos a tabela EmployeeDepartmentHistorycom a tabela Department em sua coluna comum, DepartmentID.

Exercício 9: Selecionar funcionários com seus departamentos e turnos

Exercício: Selecione nomes de departamentos distintos e nomes de turnos (sem pares duplicados) que os funcionários de cada departamento trabalham. Renomeie o nome do departamento para DepartmentName e o nome do turno para ShiftName.

Solução:

SELECT DISTINCT d.Name AS DepartmentName, s.Name AS ShiftName
FROM HumanResources.EmployeeDepartmentHistory AS edh
JOIN HumanResources.Department AS d
ON edh.DepartmentID = d.DepartmentID
JOIN HumanResources.Shift AS s
ON edh.ShiftID = s.ShiftID;

Explicação: Selecionamos a coluna Name da tabela Department e a coluna Name da tabela Shift fornecendo nomes de alias para elas usando a palavra-chave AS. Usamos DISTINCT para selecionar pares distintos.

Para selecionar nomes de departamentos e nomes de turnos, devemos unir essas três tabelas:

  • Unimos a tabela EmployeeDepartmentHistory com a tabela Department na tabela DepartmentID
  • Unimos a tabela EmployeeDepartmentHistory com a tabela Shift na tabela ShiftID

Cada uma das cláusulas JOIN tem uma cláusula ON que define as colunas comuns nas quais a união é realizada.

Exercício 10: Selecionar funcionários contratados após 2010 com seus departamentos e turnos

Exercício: Selecione os IDs dos funcionários, os nomes dos departamentos e os nomes dos turnos. Inclua somente os funcionários contratados depois de 01/01/2010 e que trabalham em departamentos dos grupos de Manufatura e Garantia de Qualidade.

Solução:

SELECT e.BusinessEntityID, d.Name, s.Name
FROM HumanResources.Employee AS e
JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.BusinessEntityID = edh.BusinessEntityID
JOIN HumanResources.Department AS d
ON edh.DepartmentID = d.DepartmentID
JOIN HumanResources.Shift AS s
ON edh.ShiftID = s.ShiftID
WHERE e.HireDate > '2010-01-01'
AND d.GroupName IN ('Manufacturing', 'Quality Assurance');

Explicação: Selecionamos a coluna BusinessEntityID da tabela Employees a coluna Name da tabela Department e a coluna Name da tabela Shift.

Para selecionar os IDs dos funcionários junto com os nomes dos departamentos e dos turnos, precisamos usar três uniões:

  • Unimos a tabela Employee com a tabela EmployeeDepartmentHistory na coluna BusinessEntityID.
  • Unimos a tabela EmployeeDepartmentHistory com a tabela Department na coluna DepartmentID
  • Juntamos a tabela EmployeeDepartmentHistory com a tabela Shift na coluna ShiftID.

Em seguida, fornecemos as condições da cláusula WHERE da seguinte forma:

  • Queremos listar todos os funcionários contratados após 1º de janeiro de 2010, portanto, impomos uma condição na coluna HireDate: HireDate > '2010-01-01'.
  • Queremos listar somente os funcionários que pertencem a determinados grupos de departamentos, portanto, usamos a palavra-chave IN para criar essa condição: GroupName IN ('Manufacturing', 'Quality Assurance').

Parte 3: Agrupamento e agregação de dados

Nesta parte, agruparemos e agregaremos dados para que possamos realizar operações matemáticas nos dados selecionados.

Observação: para escrever consultas corretas, você deve primeiro se familiarizar com os dados armazenados nas tabelas relevantes.

Exercício 11: Selecionar o maior e o menor número de horas de licença médica

Exercício: Selecione o número mínimo e máximo de horas de licença médica tiradas pelos funcionários.

Solução:

SELECT MIN(SickLeaveHours) AS MinSickLeaveHours,
       MAX(SickLeaveHours) AS MaxSickLeaveHours
FROM HumanResources.Employee;

Explicação: Usamos as funções de agregação MIN() e MAX() - fornecendo a coluna SickLeaveHours da tabela Employee como argumento - para selecionar os números mínimo e máximo de horas de licença médica tiradas pelos funcionários.

Exercício 12: Selecionar o número médio de horas de férias por cargo

Exercício: Selecione os cargos e o número médio de horas de férias por cargo.

Solução:

SELECT JobTitle, AVG(VacationHours) AS AvgVacationHours
FROM HumanResources.Employee
GROUP BY JobTitle;

Explicação: Selecionamos a coluna JobTitle da tabela Employee tabela.

Usamos a função de agregação AVG() para obter o número médio de horas de férias para cada cargo. Queremos ter grupos de dados com base nos valores distintos da coluna JobTitle; isso exige que usemos a cláusula GROUP BY com a coluna JobTitle como argumento.

Exercício 13: Selecionar a contagem de funcionários com base em seu gênero

Exercício: Selecione o gênero dos funcionários e a contagem de funcionários de cada gênero.

Solução:

SELECT Gender, COUNT(*) AS Count
FROM HumanResources.Employee
GROUP BY Gender;

Explicação: Selecionamos a coluna Gender da tabela Employee tabela.

Usamos a função de agregação COUNT() para obter a contagem de funcionários de cada gênero. Isso exige que usemos a cláusula GROUP BY com a coluna Gender como argumento; queremos ter grupos de dados com base nos valores distintos da coluna Gender.

Exercício 14: Selecione o número de departamentos em cada grupo

Exercício: Encontre o número de departamentos em cada grupo de departamentos. Liste apenas os nomes de grupos de departamentos que tenham mais de dois departamentos.

Solução:

SELECT GroupName, COUNT(*) AS DepartmentsCount
FROM HumanResources.Department
GROUP BY GroupName
HAVING COUNT(*) > 2;

Explicação: Selecionamos a coluna GroupName da tabela Department.

Usamos a função de agregação COUNT() para obter a contagem de departamentos em cada grupo de departamentos. Isso exige que usemos a cláusula GROUP BY com a coluna GroupName como argumento.

Para impor uma condição à função de agregação, usamos a cláusula HAVING após a cláusula GROUP BY: HAVING COUNT(*) > 2.

Exercício 15: Selecione a soma das horas de licença médica para cada departamento

Exercício: Selecione os nomes dos departamentos e a soma das horas de licença médica tiradas pelos funcionários que trabalham atualmente em cada departamento. Renomeie essa coluna para SumSickLeaveHours.

Solução:

SELECT d.Name, SUM(e.SickLeaveHours) AS SumSickLeaveHours
FROM HumanResources.Employee AS e
JOIN HumanResources.EmployeeDepartmentHistory AS edh
ON e.BusinessEntityID = edh.BusinessEntityID
JOIN HumanResources.Department AS d
ON edh.DepartmentID = d.DepartmentID
WHERE edh.EndDate IS NULL
GROUP BY d.Name;

Explicação: Selecionamos a coluna Name na seção Department.

Usamos a função agregada SUM() para obter a soma das horas de licença médica usadas pelos funcionários de cada departamento. Isso exige que usemos a cláusula GROUP BY com a coluna Name da tabela Department como argumento.

Devemos unir a tabela Employee com a tabela EmployeeDepartmentHistory na coluna BusinessEntityID. Em seguida, unimos a tabela EmployeeDepartmentHistorycom a tabela Department na coluna DepartmentID.

Como consideramos apenas os funcionários que trabalham atualmente em qualquer departamento, impomos a condição de que a coluna EndDate da tabela EmployeeDepartmentHistory deve ser NULL.

Parte 4: Outros recursos SQL

Nesta parte, abordaremos as subconsultas (ou seja, consultas aninhadas dentro de consultas), operadores como UNION e INTERSECT e expressões de tabela comuns (CTEs).

Observação: Para escrever consultas corretas, você deve primeiro se familiarizar com os dados armazenados nas tabelas relevantes.

Exercício 16: Selecionar funcionários com sua taxa de pagamento atual

Exercício: Selecionar os IDs dos funcionários e seus salários atuais.

Solução:

SELECT e.BusinessEntityID, e.Rate AS CurrentPayRate
FROM HumanResources.EmployeePayHistory AS e
WHERE e.RateChangeDate = (
			SELECT MAX(e2.RateChangeDate)
			FROM HumanResources.EmployeePayHistory AS e2
			WHERE e2.BusinessEntityID = e.BusinessEntityID
		);

Explicação: Selecionamos as colunas BusinessEntityID e Rate da tabela EmployeePayHistory tabela.

Como a tabela EmployeePayHistory armazena o histórico das taxas de pagamento de cada funcionário, precisamos impor uma condição para que o valor da coluna RateChangeDate seja igual à data mais recente de alteração da taxa de pagamento de um funcionário. Para isso, definimos uma subconsulta na cláusula WHERE que seleciona a data mais recente em que a taxa de pagamento foi modificada. Essa subconsulta usa a função de agregação MAX() para selecionar a data mais recente.

Estamos selecionando o RateChangeDate mais recente para cada funcionário separadamente, portanto, adicionamos uma cláusula WHERE na subconsulta para fazer a correspondência dos IDs dos funcionários entre as consultas externa e interna.

Exercício 17: Selecionar as taxas de pagamento mínima, média e máxima

Exercício: Selecione as taxas de pagamento mínima, média e máxima das taxas de pagamento atuais dos funcionários.

Solução:

SELECT MIN(CurrentPayRate) AS MinPayRate,
       AVG(CurrentPayRate) AS AvgPayRate,
       MAX(CurrentPayRate) AS MaxPayRate
FROM (
		SELECT e.BusinessEntityID, e.Rate AS CurrentPayRate
		FROM HumanResources.EmployeePayHistory AS e
		WHERE e.RateChangeDate = (
				SELECT MAX(e2.RateChangeDate)
				FROM HumanResources.EmployeePayHistory AS e2
				WHERE e2.BusinessEntityID = e.BusinessEntityID
			)
) AS cpr;

Explicação: Usamos as funções de agregação MIN(), AVG() e MAX() para selecionar os salários mínimo, médio e máximo, fornecendo a coluna CurrentPayRate da subconsulta como argumento.

Usamos a subconsulta na cláusula FROM. Essa subconsulta seleciona as taxas de pagamento atuais de cada funcionário, conforme explicado no Exercício 16.

Observe que essa solução aninha duas subconsultas. Primeiro, usamos uma subconsulta na cláusula FROM. E, em seguida, essa subconsulta usa uma subconsulta em sua própria cláusula WHERE.

Exercício 18: Selecionar IDs de funcionários com suas horas fora do expediente

Exercício: Selecione todos os IDs de funcionários que tiraram mais de 60 horas de férias ou que tiraram mais de 60 horas de licença médica.

Solução:

SELECT BusinessEntityID
FROM HumanResources.Employee
GROUP BY BusinessEntityID
HAVING SUM(VacationHours) > 60

UNION

SELECT BusinessEntityID
FROM HumanResources.Employee
GROUP BY BusinessEntityID
HAVING SUM(SickLeaveHours) > 60;

Explicação: A primeira consulta seleciona a coluna BusinessEntityID da tabela Employee e usa a função de agregação SUM() para somar o número de horas de férias tiradas por cada funcionário. Agrupamos pelo ID do funcionário e impomos a condição de que a soma deve ser maior que 60.

De forma análoga, a segunda consulta seleciona a coluna BusinessEntityID da tabela Employee e usa a função de agregação SUM() para somar o número de horas de licença médica tiradas por cada funcionário. Agrupamos pelo ID do funcionário e impomos a condição de que a soma deve ser maior que 60.

O operador UNION combina a saída das duas consultas.

Exercício 19: Selecionar IDs de funcionários com determinados cargos e departamentos

Exercício: Selecione os IDs dos funcionários com os cargos "Representante de Vendas" ou "Designer de Ferramentas" e que trabalharam (ou estão trabalhando) nos departamentos de Vendas ou Marketing.

Solução:

SELECT e.BusinessEntityID
FROM HumanResources.Employee AS e
WHERE e.JobTitle IN ('Sales Representative', 'Tool Designer')

INTERSECT

SELECT edh.BusinessEntityID
FROM HumanResources.EmployeeDepartmentHistory AS edh
JOIN HumanResources.Department AS d
ON edh.DepartmentID = d.DepartmentID
WHERE d.Name IN ('Sales', 'Marketing');

Explicação: A primeira consulta seleciona a coluna BusinessEntityID da tabela Employee da tabela. Ela filtra a coluna JobTitle para incluir somente representantes de vendas e projetistas de ferramentas.

A segunda consulta seleciona a coluna BusinessEntityID da tabela EmployeeDepartmentHistory tabela. Ela filtra o nome do departamento para incluir apenas os departamentos de Vendas e Marketing.

O operador INTERSECT encontra o resultado comum das duas consultas, ou seja, ele produzirá somente os IDs dos funcionários que atendem às condições da cláusula WHERE de ambas as consultas.

Exercício 20: listar representantes de vendas e gerentes de marketing com seus departamentos

Exercício: Selecione os IDs, os cargos e os nomes dos departamentos dos funcionários associados às funções de representante de vendas ou gerente de marketing.

Solução:

SELECT e.BusinessEntityID, e.JobTitle, d.Name AS DepartmentName
FROM HumanResources.Employee AS e
JOIN HumanResources.EmployeeDepartmentHistory AS edh 
ON e.BusinessEntityID = edh.BusinessEntityID
JOIN HumanResources.Department AS d
ON edh.DepartmentID = d.DepartmentID
WHERE e.JobTitle IN ('Sales Representative', 'Marketing Manager');

Explicação: A consulta usa um JOIN para vincular a tabela Employee com a tabela EmployeeDepartmentHistory com base na coluna BusinessEntityID. Essa junção garante que o registro de cada funcionário seja conectado ao histórico do departamento.

Outro JOIN vincula a tabela EmployeeDepartmentHistory à tabela DepartmentDepartmentID Isso permite que a consulta recupere informações de departamento relacionadas ao histórico de trabalho do funcionário.

A cláusula WHERE filtra os resultados para incluir somente os funcionários cujos cargos sejam "Representante de vendas" ou "Gerente de marketing". Essa filtragem é feita usando o operador IN, que especifica os cargos desejados. A estrutura da consulta combina e filtra com eficiência os dados de várias tabelas para retornar os cargos relevantes dos funcionários e seus departamentos associados.

Pratique SQL com exercícios do AdventureWorks!

Neste artigo, você explorou os fundamentos do SQL por meio de exercícios com o banco de dados AdventureWorks. Você aprendeu a realizar consultas de tabela única com SELECT, combinar dados de tabela usando JOIN, agrupar dados com GROUP BY e usar funções agregadas como COUNT(), AVG(), SUM(), MIN() e MAX(). Além disso, você se aprofundou em subconsultas, UNION e INTERSECT.

Para obter mais exercícios com soluções e explicações detalhadas, confira nossos artigos 10 Beginner Trilha de Práticas em SQL Exercises With Solutions e SQL Joins: 12 Practice Questions with Detailed Answers. Aprofunde-se nas oportunidades de prática de SQL com nosso abrangente Guia para Trilha de Práticas em SQL em LearnSQL.com. E, como mencionei anteriormente, você também pode continuar a praticar com a nossa trilha Trilha de Práticas em SQL , os bancos de dados de prática de SQL ou o curso mensal gratuito de SQL.

Boa sorte em sua jornada SQL!