2

I have 2 tables - departments and employees. I want to select all columns from departments and also add a column with number of subdepartments and number of employees in each department.

Simplified tables look like this:

departments:

id      name            parent_id
---------------------------------
1       IT              NULL
2       HR              NULL
3       Bussiness       NULL
4       Web dev         1
5       Ecommerce       4
6       Advertisement   3
7       Control         3
8       Programmers     1

employees:

id      name            department_id
---------------------------------
1       Adam            1
2       Ben             8
3       Charles         7
4       David           4
5       Eugen           4
6       Frank           6
7       Gustav          6
8       Heremy          4
9       Igor            5
10      Jacob           3

Result I want is:

id      name            parent_id       department_count      employee_count
----------------------------------------------------------------------------
1       IT              NULL            2                     1
2       HR              NULL            0                     0
3       Bussiness       NULL            2                     1
4       Web dev         1               1                     3
5       Ecommerce       4               0                     1
6       Advertisement   3               0                     2
7       Control         3               0                     1
8       Programmers     1               0                     1

Here is my query, but it is not working properly. But if I remove 1 of the COUNT, the numbers are then correct. I think that the NULL values are the problem, but I don't know the solution.

SELECT d.*, COUNT(d2.parent_id) AS department_count, COUNT(e.id) AS employee_count
FROM department AS d
LEFT JOIN department AS d2 ON (d.id = d2.parent_id)
LEFT JOIN employees AS z ON (e.department_id = d.id)
GROUP BY d.id
ORDER BY d.id

Any improvement on my code is welcome.

1
  • 1
    I'm sorry, my mistake - it should have been 2 Commented Sep 16, 2014 at 7:44

2 Answers 2

7

Use d2.id in your count function with distinct,so the repeated children for a department will be counted only once

SELECT d.*,
COUNT(distinct d2.id) AS department_count,
COUNT(distinct e.id) AS employee_count
FROM department AS d
LEFT JOIN department AS d2 ON (d.id = d2.parent_id)
LEFT JOIN employees AS e ON (e.department_id = d.id)
GROUP BY d.id
ORDER BY d.id

Demo

Sign up to request clarification or add additional context in comments.

Comments

4

You can try correlated queries as they provide straightforward logic:

SELECT d.*, 
  (SELECT COUNT(*) FROM departments WHERE parent_id = d.id) as department_count,
  (SELECT COUNT(*) FROM employees WHERE department_id = d.id) as employees_count
FROM departments d

1 Comment

Correlated might be slow because they will be executed for each row of departments table

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.