简体   繁体   中英

SQL - how to get certain column with MIN and MAX id for every department?

I'm trying to select some information using SQL, but with no success. Here's what I'm trying to do.

I have 2 tables:

Table employees with following columns:

IDemployee | name    | surname  | department_id
1          | John    | Smith    | 1
2          | Jane    | Smith    | 1
3          | Neo     | Anderson | 1
4          | John    | Mason    | 2
5          | James   | Cameron  | 2
6          | Morpheus| Grumpy   | 2

Table departments with columns:

IDdepartment | name
1            | Thieves
2            | Madmen

I want to select surnames of first and last employees of every department and count of their employees. Result:

department_name | first_employee | last_employee | employee_count
Thieves         | Smith          | Anderson      | 3
Madmen          | Mason          | Grumpy        | 3

I was able to get count and ID's of first and last employees with following query:

SELECT d.IDdepartment, COUNT(*) as "employee_count", MIN(e.IDemployee) as "first_employee", MAX(e.IDemployee) as "last_employee"
        FROM ( employees e INNER JOIN departments d ON d.IDdepartment=e.department_id)
        GROUP BY d.name;

However, I can't find the right way to select their surnames. Any help would be greatly appreciated.

This is general Oracle example based on existing Oracle table. You need to use analytic functions if available in your version of SQL. You do not specify which SQL you are using. If FIRST() and LAST() analytic f-ns available in your SQL then this should work:

SELECT empno, deptno, sal,
   MIN(sal) KEEP (DENSE_RANK FIRST ORDER BY sal) OVER (PARTITION BY deptno) "Lowest",
   MAX(sal) KEEP (DENSE_RANK LAST ORDER BY sal) OVER (PARTITION BY deptno) "Highest"
 FROM scott.emp
ORDER BY deptno, sal
/

See lowest and highest salary by dept in output of above query:

DEPTNO  SAL     Lowest  Highest
---------------------------------
10      1300    1300    5000
10      2450    1300    5000
10      5000    1300    5000
20      800     800     3000
20      1100    800     3000
20      2975    800     3000
....

While there might be another way, one way is to use your query as a subquery:

SELECT d.name department_name, 
  e.surname first_employee,
  e2.surname last_employee,
  t.employee_count
FROM (
    SELECT d.IDdepartment, 
       COUNT(*) as "employee_count", 
       MIN(e.IDemployee) as "first_employee", 
       MAX(e.IDemployee) as "last_employee"
    FROM employees e 
          INNER JOIN departments d 
            ON d.IDdepartment=e.department_id
    GROUP BY d.name
  ) t JOIN employees e on t.first_employee = e.IDemployee
  JOIN employees e2 on t.last_employee = e2.IDemployee
  JOIN departments d on t.IDdepartment = d.IDdepartment

And here is the fiddle: http://sqlfiddle.com/#!2/17a5b/2

Good luck.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM