Database Basics
From an employee table (emp_no, dept, salary), you want the departments whose average salary is 300 or more, together with that average. Which SQL statement is correct?
- ASELECT dept, AVG(salary) FROM employee GROUP BY dept HAVING AVG(salary) >= 300
- BSELECT dept, AVG(salary) FROM employee WHERE AVG(salary) >= 300 GROUP BY dept
- CSELECT dept, AVG(salary) FROM employee WHERE salary >= 300 GROUP BY dept
Show answer and explanation
Answer: A. SELECT dept, AVG(salary) FROM employee GROUP BY dept HAVING AVG(salary) >= 300
Think of SQL processing in this order: WHERE selects rows from the table in FROM, GROUP BY gathers them into groups, and HAVING selects groups. WHERE is a condition on individual rows, evaluated before grouping, so aggregate functions such as AVG cannot be written in it. A condition on each group's aggregate goes in HAVING, so HAVING AVG(salary) >= 300 is the correct form. With WHERE salary >= 300, only employees earning 300 or more are selected before averaging, which means something different, the average over just those employees; a department whose overall average is below 300 still appears in the result as long as at least one of its employees earns 300 or more.
- A. Correct. A condition on each group's aggregate is written in the HAVING clause.
- B. Aggregate functions cannot be written in a WHERE clause, so this statement causes an error.
- C. This averages only employees earning 300 or more, so departments whose overall average is below 300 also appear.