Skip to content
Advertisement

Can I group by in SQL query with window function?

I need to get employees with smallest salary in their departments I did it using anti join.

But I’ve been told that it’s possible to do it using window function using one select. However I can’t group it by department_id and use it at the same time. Is that a bug or me being stupid?

SQL Developer says 00979. 00000 – “not a GROUP BY expression”

Advertisement

Answer

If you run your second query without the group by – which you may have already tried, from the extra semicolon in what you posted – you’ll see that you get one row for every employee, each showing the minimum salary in their department. That minimum is the analytic min() because it has a window clause. The PARTITION BY is the equivalent of a GROUP BY, but without the aggregation over the whole result set.

The simplest way to get the same result (almost) is to use the RANK() analytic function instead, which ranks the values based on the partition and order you supply, while allowing for ties:

For departments 20 and 30 you can see the row ranked 1 is the lowest salary. For department 90 there are two employees ranked 1, because they have the same lowest salary.

You can use that as an inline view and select just those rows ranked number 1:

If you didn’t have to worry about ties there is an even simpler alternative, but it ins’t appropriate here.

Notice that this gives you one more row than your original query. You are joining on sml.department_id = emp.department_id. If the department ID is null, as it is for employee 178, that join fails because you can’t compare null to null with equality tests. Because this solution doesn’t have a join, that doesn’t apply, and you see that employee in the results.

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement