Volver a la lista de artículos Artículos
Lectura de 19 minutos

Práctica de SQL para principiantes: Ejercicios AdventureWorks

Índice

Perfeccione sus habilidades SQL con ejercicios prácticos utilizando la base de datos de muestra de AdventureWorks. Practique las funciones esenciales de SQL utilizando escenarios reales.

Practicar SQL es importante si desea mejorar en su uso. Este artículo contiene 20 ejercicios para principiantes que utilizan la base de datos de ejemplo AdventureWorks de Microsoft. Esta base de datos está diseñada para mostrar cómo funciona SQL Server. Representa una empresa ficticia de fabricación de bicicletas llamada AdventureWorks Cycles e incluye cinco esquemas: RecursosHumanos, Persona, Producción, Compras y Ventas. Esto la hace ideal para aprender y practicar SQL.

La base de datos AdventureWorks cubre varios escenarios empresariales como fabricación, ventas, compras, gestión de productos, gestión de contactos y recursos humanos. Esto la convierte en un excelente recurso para aprender y practicar SQL, ya que proporciona una amplia gama de datos y procesos empresariales con los que trabajar. Al practicar con esta base de datos, puede adquirir experiencia práctica con datos y escenarios del mundo real; esto le ayudará a comprender cómo escribir consultas eficientes y resolver problemas de datos de forma eficaz.

Si quieres probar otras bases de datos de ejemplo, consulta nuestra lista de las fuentes de datos más interesantes para la práctica de SQL. Sin embargo, configurar tu propio entorno de práctica de SQL puede llevarte tiempo. Para una práctica rápida, pruebe nuestra pistaEjercicio de SQL o nuestras bases de datos de práctica de SQL. También publicamos un curso gratuito de SQL cada mes para ayudarte a seguir aprendiendo.

Ahora, ¡comencemos a practicar SQL con los ejercicios de AdventureWorks!

Revisión de la base de datos de AdventureWorks

La base de datos AdventureWorks consta de cinco esquemas de base de datos (es decir, estructuras de base de datos utilizadas para agrupar tablas de datos), que incluyen HumanResources, Person, Production, Purchasing y Sales. En los siguientes ejercicios, utilizaremos el esquema HumanResources.

Empecemos analizando el esquema:

Base de datos AdventureWorks

En primer lugar, repasemos los conceptos de claves primaria y foránea:

  • La clave primaria (PK) es una columna (o un conjunto de columnas) que identifica de forma única cada fila de una tabla. Por ejemplo, la columna BusinessEntityID es la clave primaria de la tabla Employee porque cada empleado tiene asignado un número de identificación único.
  • La clave externa (FK) es una columna (o un conjunto de columnas) que vincula dos tablas. Tenga en cuenta que la clave externa de una tabla es la clave primaria de otra tabla, por lo que las dos tablas están vinculadas. Por ejemplo, la columna BusinessEntityID es la clave primaria de la tabla Employee y también una clave externa en la tabla JobCandidate de la tabla. Esto vincula ambas tablas y permite que la tabla JobCandidate a las filas de la tabla Employee

Analicemos ahora las tablas del esquema.

La tabla Employee almacena información sobre los empleados y es la tabla principal de este esquema. Está enlazada con las siguientes tablas:

  • La tabla JobCandidate almacena los currículos de los solicitantes de empleo. La columna BusinessEntityID es un PK en la tabla Employee y un FK en la tabla JobCandidate El PK de la tabla JobCandidate es la columna JobCandidateID.
  • La tabla EmployeePayHistory tabla almacena el historial de las tarifas salariales de los empleados. La columna BusinessEntityID es un PK en la tabla Employee y un FK en la tabla EmployeePayHistory Observe que la columna BusinessEntityID de la tabla EmployeePayHistory tabla es al mismo tiempo un FK y parte del PK. El PK de la tabla EmployeePayHistory tabla comprende las columnas BusinessEntityID y RateChangeDate. Esto se denomina clave primaria compuesta.
  • La tabla EmployeeDepartmentHistory almacena el historial de los departamentos de los empleados. La columna BusinessEntityID es una PK en la tabla Employee y una FK en la tabla EmployeeDepartmentHistory Observe que la columna BusinessEntityID de la tabla EmployeeDepartmentHistory tabla es a la vez un FK y parte del PK. El PK de la tabla EmployeeDepartmentHistory está formada por las columnas BusinessEntityID, DepartmentID, ShiftID, y StartDate. Se trata de otra clave primaria compuesta.

La tabla EmployeeDepartmentHistory almacena información sobre los empleados y sus departamentos a lo largo del tiempo y puede considerarse como otra tabla principal de este esquema. Está vinculada con las siguientes tablas:

  • La tabla Shift almacena información sobre los turnos disponibles. La columna ShiftID es un PK en la tabla Shift y un FK en la tabla EmployeeDepartmentHistory Observe que la columna ShiftID es a la vez un FK y parte del PK en la tabla EmployeeDepartmentHistory tabla.
  • La tabla Department almacena información sobre los departamentos. La columna DepartmentID es un PK en la tabla Department y un FK en la tabla EmployeeDepartmentHistory Observe que la columna DepartmentID es a la vez un FK y parte del PK en la tabla EmployeeDepartmentHistory de la tabla.

Ahora estamos listos para comenzar nuestros ejercicios de AdventureWorks.

Ejercicios de AdventureWorks para Principiantes

Cubriremos todos los aspectos básicos de SQL (e incursionaremos en algunas funciones avanzadas) a medida que avancemos en este artículo:

  • Consultas de tabla única para recuperar y filtrar datos.
  • Consultas de múltiples tablas que utilizan JOINs para combinar datos de dos o más tablas.
  • Agrupación y agregación de datos para realizar operaciones matemáticas con los datos seleccionados.
  • Otras características relevantes de SQL como subconsultas, UNION e INTERSECT, y expresiones comunes de tabla (CTEs).

Parte 1: Consultas de Tabla Única

En esta parte, recuperaremos y filtraremos datos.

Nota: Para escribir consultas correctas, primero debe familiarizarse con los datos almacenados en las tablas.

Ejercicio 1: Seleccionar los cargos de todos los empleados varones solteros

Ejercicio: Seleccionar el puesto de todos los empleados solteros.

Solución:

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

Explicación: Seleccionamos la columna JobTitle de la Employee tabla. Aquí la sintaxis SQL se puede leer exactamente como en inglés llano.

Las condiciones de filtrado se colocan en la cláusula WHERE:

  • Queremos seleccionar sólo empleados masculinos, por lo que imponemos una condición en la columna Gender: Gender = 'M'.
  • Queremos seleccionar sólo empleados que no estén casados, así que imponemos otra condición en la columna MaritalStatus: MaritalStatus != 'M'.

Como ambas condiciones deben aplicarse al mismo tiempo, utilizamos el operador AND para combinarlas.

Ejercicio 2: Seleccionar empleados cuyo salario sea igual o superior a 50

Ejercicio: Seleccionar en BusinessEntityID, Rate, y RateChangeDate a todos los empleados cuya tasa de pago haya sido alguna vez 50 o más.

Solución:

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

Explicación: Seleccionamos tres columnas - BusinessEntityID, Rate, y RateChangeDate - de la EmployeePayHistory tabla.

A continuación, proporcionamos una condición de filtrado en la cláusula WHERE para recuperar sólo aquellos cuya tasa de pago haya sido alguna vez mayor o igual a 50: Rate >= 50.

Ejercicio 3: Seleccionar todos los empleados que se incorporaron a nuevos departamentos en 2008

Ejercicio: Seleccione las cláusulas BusinessEntityID, DepartmentID, y StartDate para cada empleado que empezó a trabajar en cualquier departamento en 2008.

Solución:

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

Explicación: Seleccionamos los ID de los empleados (BusinessEntityID), los ID de los departamentos (DepartmentID) y la fecha en la que el empleado se incorporó a ese departamento (StartDate) de la tabla EmployeeDepartmentHistory tabla.

Como queremos listar sólo los empleados que se incorporaron a nuevos departamentos en 2008, imponemos una condición en la columna StartDate: StartDate BETWEEN '2008-01-01' AND '2008-12-31'.

Esta condición se explica por sí misma, ya que es comprensible en inglés sencillo. Queremos que el valor de StartDate esté comprendido entre el 1 de enero de 2008 y el 31 de diciembre de 2008, asegurándonos de que cubrimos todos los días de 2008.

Ejercicio 4: Seleccionar departamentos cuyos nombres coincidan con el patrón

Ejercicio: Seleccionar los ID de departamento, nombres y nombres de grupo de todos los departamentos cuyo nombre empiece por 'Prod' O de todos los departamentos cuyo nombre de grupo termine por 'ring'.

Solución:

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

Explicación: Seleccionamos las columnas DepartmentID, Name, y GroupName de la Department de la tabla.

A continuación, proporcionamos las condiciones de la cláusula WHERE:

  • Queremos seleccionar departamentos cuyo nombre empiece por 'Prod', así que imponemos una condición a la columna Name: Name LIKE 'Prod%'.
  • También queremos seleccionar los departamentos cuyo nombre de grupo termine en "ring", por lo que imponemos una condición en la columna GroupName: GroupName LIKE '%ring'.

La palabra clave LIKE nos permite definir el patrón con el que debe coincidir el valor de la columna. Por ejemplo, queremos que la columna Name empiece por 'Prod', por lo que el patrón es 'Prod%'; % significa cualquier secuencia de caracteres.

Como queremos encontrar todos los registros en los que al menos una de las condiciones sea cierta, utilizamos la palabra clave OR.

Ejercicio 5: Seleccionar departamentos que pertenecen a determinados grupos

Ejercicio: Seleccionar nombres de departamentos que pertenezcan al grupo "Investigación y Desarrollo" o al grupo "Fabricación".

Solución:

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

Explicación: Seleccionamos la columna Nombre de la Department tabla.

Como queremos listar los departamentos que pertenecen a los grupos definidos, utilizamos la palabra clave IN en la condición de la cláusula WHERE: GroupName IN ('Research and Development', 'Manufacturing').

Esto asegura que se muestren todos los departamentos que pertenecen a los grupos listados en la palabra clave IN.

Parte 2: Consultas a Múltiples Tablas

En esta parte, utilizaremos JOINs para combinar datos de múltiples tablas.

Nota: Para escribir consultas correctas, primero debe familiarizarse con los datos almacenados en las tablas relevantes.

Ejercicio 6: Seleccionar empleados y sus departamentos

Ejercicio: Seleccionar los ID de los empleados con todos los nombres de los departamentos donde han trabajado alguna vez.

Solución:

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

Explicación: Seleccionamos la columna BusinessEntityID de la EmployeeDepartmentHistory y la columna Name de la tabla Department tabla.

Unimos estas dos tablas usando la cláusula JOIN en su columna común, DepartmentID.

Ejercicio 7: Seleccionar los cargos de las empleadas y las fechas de cambio de departamento

Ejercicio: Seleccionar el ID de la empleada y el cargo junto con las fechas en las que la empleada cambió de departamento (StartDate) para todas las empleadas.

Solución:

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';

Explicación: Seleccionamos las columnas BusinessEntityID y JobTitle de la Employee y la columna StartDate de la tabla EmployeeDepartmentHistory de la tabla.

Utilizamos la cláusula JOIN para unir las tablas en su columna común, BusinessEntityID.

Como queremos listar esta información sólo para las empleadas, imponemos una condición en la columna Gender: e.Gender = 'F'.

Ejercicio 8: Seleccionar puestos de trabajo por departamento

Ejercicio: Seleccione los títulos de los puestos y sus correspondientes nombres de departamento para encontrar todos los títulos de puestos que se han utilizado alguna vez en cada departamento. No incluya múltiplos del mismo puesto.

Solución:

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;

Explicación: Seleccionamos la columna JobTitle de la Employee y la columna Name de la tabla Department de la tabla.

Para seleccionar puestos de trabajo distintos (es decir, sin duplicados), utilizamos la palabra clave DISTINCT antes de los nombres de las columnas.

Debemos unir la tabla Employee con la tabla EmployeeDepartmentHistory en su columna común, BusinessEntityID. A continuación, unimos la tabla EmployeeDepartmentHistorycon la tabla Department tabla en su columna común, DepartmentID.

Ejercicio 9: Seleccionar empleados con sus departamentos y turnos

Ejercicio: Seleccionar los nombres de departamentos y turnos distintos (sin pares duplicados) en los que trabajan los empleados de cada departamento. Renombre el nombre del departamento a DepartmentName y el nombre del turno a ShiftName.

Solución:

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;

Explicación: Seleccionamos la columna Nombre de la Department y la columna Name de la tabla Shift proporcionándoles alias mediante la palabra clave AS. Utilizamos DISTINCT para seleccionar pares distintos.

Para seleccionar nombres de departamentos y nombres de turnos, debemos unir estas tres tablas:

  • Unimos la tabla EmployeeDepartmentHistory con la tabla Department en la tabla DepartmentID
  • Unimos la tabla EmployeeDepartmentHistory con la tabla Shift en la tabla ShiftID

Cada una de las cláusulas JOIN tiene una cláusula ON que define las columnas comunes sobre las que se realiza el join.

Ejercicio 10: Seleccionar empleados contratados después de 2010 con sus departamentos y turnos

Ejercicio: Seleccione los ID de los empleados, los nombres de los departamentos y los nombres de los turnos. Incluya sólo empleados contratados después del 01-01-2010 y que trabajen para departamentos dentro de los grupos de Fabricación y Control de Calidad.

Solución:

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');

Explicación: Seleccionamos la columna BusinessEntityID de la Employees la columna Name de la tabla Department y la columna Name de la tabla Shift.

Para seleccionar los ID de los empleados junto con los nombres de los departamentos y los nombres de los turnos, debemos utilizar tres uniones:

  • Unimos la tabla Employee con la tabla EmployeeDepartmentHistory en la columna BusinessEntityID.
  • Unimos la tabla EmployeeDepartmentHistory con la tabla Department en la columna DepartmentID
  • Unimos la tabla EmployeeDepartmentHistory con la tabla Shift en la columna ShiftID.

A continuación, ponemos las condiciones de la cláusula WHERE de la siguiente manera:

  • Queremos listar todos los empleados contratados después del 1 de enero de 2010, así que imponemos una condición en la columna HireDate: HireDate > '2010-01-01'.
  • Queremos listar sólo los empleados que pertenecen a ciertos grupos de departamentos, así que utilizamos la palabra clave IN para crear esta condición: GroupName IN ('Manufacturing', 'Quality Assurance').

Parte 3: Agrupación y agregación de datos

En esta parte, agruparemos y agregaremos datos para poder realizar operaciones matemáticas con los datos seleccionados.

Nota: Para escribir consultas correctas, primero debe familiarizarse con los datos almacenados en las tablas relevantes.

Ejercicio 11: Seleccionar las horas de baja por enfermedad más altas y más bajas

Ejercicio: Seleccionar el número mínimo y máximo de horas de baja por enfermedad disfrutadas por los empleados.

Solución:

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

Explicación: Usamos las funciones agregadas MIN() y MAX() - proporcionando la columna SickLeaveHours de la Employee para seleccionar el número mínimo y máximo de horas de baja de los empleados.

Ejercicio 12: Seleccionar el número medio de horas de vacaciones por puesto de trabajo

Ejercicio: Seleccionar los puestos de trabajo y el número medio de horas de vacaciones por puesto.

Solución:

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

Explicación: Seleccionamos la columna JobTitle de la Employee tabla.

Usamos la función agregada AVG() para obtener el promedio de horas de vacaciones por cada cargo. Queremos tener grupos de datos basados en los valores distintos de la columna JobTitle; esto requiere que utilicemos la cláusula GROUP BY con la columna JobTitle como argumento.

Ejercicio 13: Seleccionar el recuento de empleados en función de su sexo

Ejercicio: Seleccionar el género de los empleados y el recuento de empleados de cada género.

Solución:

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

Explicación: Seleccionamos la columna Gender de la Employee tabla.

Utilizamos la función agregada COUNT() para obtener el recuento de empleados de cada sexo. Esto requiere que utilicemos la cláusula GROUP BY con la columna Gender como argumento; queremos tener grupos de datos basados en los valores distintos de la columna Gender.

Ejercicio 14: Seleccionar el recuento de departamentos en cada grupo

Ejercicio: Encuentre la cantidad de departamentos en cada grupo de departamentos. Enumere sólo aquellos nombres de grupos de departamentos que tengan más de dos departamentos.

Solución:

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

Explicación: Seleccionamos la columna GroupName de la tabla Departamentos.

Utilizamos la función agregada COUNT() para obtener el recuento de departamentos en cada grupo de departamentos. Esto requiere que utilicemos la cláusula GROUP BY con la columna GroupName como argumento.

Para imponer una condición a la función agregada, utilizamos la cláusula HAVING después de la cláusula GROUP BY: HAVING COUNT(*) > 2.

Ejercicio 15: Seleccionar la suma de horas de baja por enfermedad de cada departamento

Ejercicio: Seleccione los nombres de los departamentos y la suma de horas de baja por enfermedad de los empleados que trabajan actualmente en cada departamento. Cambie el nombre de esta columna a SumSickLeaveHours.

Solución:

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;

Explicación: Seleccionamos la columna Nombre del Department.

Utilizamos la función agregada SUM() para obtener la suma de horas de baja por enfermedad utilizadas por los empleados para cada departamento. Para ello debemos utilizar la cláusula GROUP BY con la columna Nombre de la tabla Department como argumento.

Debemos unir la tabla Employee con la tabla EmployeeDepartmentHistory en la columna BusinessEntityID. A continuación, unimos la tabla EmployeeDepartmentHistorycon la tabla Department en la columna DepartmentID.

Como sólo tenemos en cuenta a los empleados que trabajan actualmente en cualquier departamento, imponemos la condición de que la columna EndDate de la tabla EmployeeDepartmentHistory tabla debe ser NULL.

Parte 4: Otras funciones de SQL

En esta parte, trataremos las subconsultas (es decir, las consultas anidadas dentro de otras consultas), los operadores como UNION y INTERSECT, y las expresiones comunes de tabla (CTE).

Nota: Para escribir consultas correctas, primero debes familiarizarte con los datos almacenados en las tablas correspondientes.

Ejercicio 16: Seleccionar empleados con su salario actual

Ejercicio: Seleccionar los identificadores de los empleados y su salario actual.

Solución:

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
		);

Explicación: Seleccionamos las columnas BusinessEntityID y Tarifa de la EmployeePayHistory tabla.

Dado que la tabla EmployeePayHistory almacena el historial de las tarifas salariales de cada empleado, necesitamos imponer una condición para que el valor de la columna RateChangeDate sea igual a la fecha más reciente de modificación de la tarifa salarial de un empleado. Para ello, definimos una subconsulta en la cláusula WHERE que selecciona la fecha más reciente en la que se modificó la tarifa salarial. Esta subconsulta utiliza la función agregada MAX() para seleccionar la fecha más reciente.

Estamos seleccionando la RateChangeDate más reciente para cada empleado por separado, por lo que añadimos una cláusula WHERE en la subconsulta para hacer coincidir los ID de los empleados entre las consultas externas e internas.

Ejercicio 17: Seleccionar el salario mínimo, medio y máximo

Ejercicio: Seleccionar las tarifas salariales mínima, media y máxima de las tarifas salariales actuales de los empleados.

Solución:

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;

Explicación: Usamos las funciones agregadas MIN(), AVG(), y MAX() para seleccionar los salarios mínimo, medio y máximo, proporcionando la columna CurrentPayRate de la subconsulta como argumento.

Utilizamos la subconsulta en la cláusula FROM. Esta subconsulta selecciona los salarios actuales de cada empleado, tal y como se explica en el Ejercicio 16.

Observe que esta solución anida dos subconsultas. Primero, utilizamos una subconsulta en la cláusula FROM. Y luego esa subconsulta utiliza una subconsulta en su propia cláusula WHERE.

Ejercicio 18: Seleccionar IDs de empleados con sus horas fuera de oficina

Ejercicio: Seleccionar todos los ID de empleados que tomaron más de 60 horas de vacaciones o que tomaron más de 60 horas de licencia por enfermedad.

Solución:

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;

Explicación: La primera consulta selecciona la columna BusinessEntityID de la tabla Employee y utiliza la función agregada SUM() para sumar el número de horas de vacaciones tomadas por cada empleado. Agrupamos por el ID del empleado e imponemos la condición de que la suma sea superior a 60.

Análogamente, la segunda consulta selecciona la columna BusinessEntityID de la tabla Employee y utiliza la función agregada SUM() para sumar el número de horas de baja por enfermedad de cada empleado. Agrupamos por el ID del empleado e imponemos la condición de que la suma sea superior a 60.

El operador UNION combina la salida de ambas consultas.

Ejercicio 19: Seleccionar IDs de empleados con determinados cargos y departamentos

Ejercicio: Seleccione los ID de los empleados que tengan los títulos de trabajo "Representante de ventas" o "Diseñador de herramientas" y que hayan trabajado (o estén trabajando) en los departamentos de Ventas o Marketing.

Solución:

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');

Explicación: La primera consulta selecciona la columna BusinessEntityID de la tabla Employee de la tabla. Filtra la columna JobTitle para incluir sólo a los representantes de ventas y los diseñadores de herramientas.

La segunda consulta selecciona la columna BusinessEntityID de la tabla. EmployeeDepartmentHistory de la tabla. Filtra el nombre del departamento para incluir sólo los departamentos de Ventas y Marketing.

El operador INTERSECT encuentra la salida común de las dos consultas, es decir, sólo mostrará los ID de los empleados que cumplan las condiciones de la cláusula WHERE de ambas consultas.

Ejercicio 20: Listar representantes de ventas y gerentes de marketing con sus departamentos

Ejercicio: Seleccionar los IDs, cargos y nombres de departamento de los empleados asociados con los roles de Representante de Ventas o Gerente de Marketing.

Solución:

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');

Explicación: La consulta utiliza un JOIN para enlazar la tabla Employee con la tabla EmployeeDepartmentHistory basada en la columna BusinessEntityID. Esta unión garantiza que el registro de cada empleado esté conectado con el historial de su departamento.

Otro JOIN vincula la tabla EmployeeDepartmentHistory con la tabla Department mediante la cláusula DepartmentID. Esto permite que la consulta recupere la información del departamento relacionada con el historial laboral del empleado.

La cláusula WHERE filtra los resultados para incluir sólo a aquellos empleados cuyo cargo sea "Representante de ventas" o "Director de marketing". Este filtrado se realiza mediante el operador IN, que especifica los puestos deseados. La estructura de la consulta combina y filtra eficientemente datos de múltiples tablas para devolver los títulos relevantes de los puestos de los empleados y sus departamentos asociados.

Practique SQL con los Ejercicios de AdventureWorks

En este artículo, exploró los fundamentos de SQL mediante ejercicios con la base de datos AdventureWorks. Aprendió cómo realizar consultas de una sola tabla con SELECT, combinar datos de tablas utilizando JOIN, agrupar datos con GROUP BY, y utilizar funciones agregadas como COUNT(), AVG(), SUM(), MIN(), y MAX(). Además, ha profundizado en las subconsultas, UNION, y INTERSECT.

Para más ejercicios con soluciones y explicaciones detalladas, consulte nuestros artículos 10 ejercicios para principiantes Ejercicio de SQL con soluciones y SQL Joins: 12 preguntas de práctica con respuestas detalladas. Profundiza en las oportunidades de práctica de SQL con nuestra completa Guía de Ejercicio de SQL en LearnSQL.com. Y como mencioné anteriormente, también puedes continuar tu práctica con nuestra pista Ejercicio de SQL , las bases de datos de práctica de SQL o el curso mensual gratuito de SQL.

¡Buena suerte en tu viaje SQL!