Click here to Skip to main content
15,886,258 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Select emp.EmpID,
emp.EmpName,
emp.PayRate,
jt.Title,
(Select AVG(payrate)
FROM yEmp) AveragePayRate
FROM yEmp emp
INNER JOIN yJobTitle jt ON emp.jobtitleid = jt.jobtitleid
WHERE payrate <= (Select AVG(payrate)
FROM yemp)
ORDER BY emp.empid

***This is what I have but I need to modify it to show Maximum payrate and Minimum Payrate. I have written the query to display the payrate that is less than or equal to the average payrate. Now I have to modify the query written for Question 5 to include the maximum and minimum payrate for all employees in the SELECT list. The AVG, MAX, and MIN are actually calculated for all employees, while the rows in the result table are for those employees who have a payrate that is less than or equal to the average payrate.

What I have tried:

I have tried to add the same select statement for AVG payrate but change the AVG to MIN and MAX
Posted
Updated 20-Jul-21 5:20am
v2

If you follow the advice given in solution 1 you will get an error returned
Quote:
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.
You would need to do this instead
SQL
Select emp.EmpID,
emp.EmpName,
emp.PayRate,
jt.Title,
(Select AVG(payrate) FROM yEmp) AveragePayRate,
(Select MIN(payrate) FROM yEmp) MinPayRate,
(Select MAX(payrate) FROM yEmp) MaxPayRate
FROM yEmp emp
INNER JOIN yJobTitle jt ON emp.jobtitleid = jt.jobtitleid
WHERE payrate <= (Select AVG(payrate)
FROM yemp)
ORDER BY emp.empid;
That is a truly awful query - you have two identical sub-queries
SQL
Select AVG(payrate) FROM yEmp
and a further two sub-queries on the same table
Straight away that is screaming to me to be refactored, and there are so many ways you could do it.

Example 1: Have a single sub-query that calculates all the values and do a cross-join on that
SQL
Select emp.EmpID,
		emp.EmpName,
		emp.PayRate,
		jt.Title,
	    calcs.avgrate,
		calcs.minrate,
		calcs.maxrate
FROM yEmp emp
INNER JOIN yJobTitle jt ON emp.jobtitleid = jt.jobtitleid
cross join (Select AVG(payrate) avgrate, MIN(payrate) minrate, MAX(payrate) maxrate from yEmp) as calcs
WHERE payrate <= calcs.avgrate 
ORDER BY emp.empid;
Example 2: Declare some variables, calculate them first then reference them in your query
SQL
declare @avrate decimal(15,2);
declare @minrate decimal(15,2);
declare @maxrate decimal(15,2);
Select @avrate = AVG(payrate), @minrate = MIN(payrate), @maxrate = MAX(payrate) from yEmp;

Select emp.EmpID,
		emp.EmpName,
		emp.PayRate,
		jt.Title,
	    @avrate as avgrate,
		@minrate as minrate,
		@maxrate as maxrate
FROM yEmp emp
INNER JOIN yJobTitle jt ON emp.jobtitleid = jt.jobtitleid
WHERE payrate <= @avrate 
ORDER BY emp.empid;
Example 3: Use a common table expression or temporary table to do the calculations and cross join to that
SQL
;with cte as
(
	Select AVG(payrate) avgrate, MIN(payrate) minrate, MAX(payrate) maxrate from yEmp
)
Select emp.EmpID,
		emp.EmpName,
		emp.PayRate,
		jt.Title,
	    cte.avgrate,
		cte.minrate,
		cte.maxrate
FROM yEmp emp
INNER JOIN yJobTitle jt ON emp.jobtitleid = jt.jobtitleid
cross join  cte
WHERE payrate <= cte.avgrate 
ORDER BY emp.empid

All the examples get all of the calculated values you need in a single hit on the table, rather than hitting the table once per each individual value
 
Share this answer
 
You do the same way you do the average one but on the main select.

Just add MAX(payrate), MIN(payrate) to your select.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900