简体   繁体   中英

mysql count on multiple columns from another table

I would like to get count of two columns from another table. For example, the source data is as below for the table called employee_master

emp_code          dept_id          sub_dept_id
1                   10                  22
2                   11                  20
3                   10                  22
4                   10                  22
5                   11                  20
6                   10                  21 

Another source table called punching_data_table as shown below which is being joined with employee_master.

emp_code          present
1                   10:01 AM
2                   10:02 AM
3                   10:02 AM
4                   10:03 AM
5                   10:11 AM
6                   10:09 AM      //biometric punching time shown

The result is suppose to look like below.

dept_id     dept_count     sub_dept_id      sub_dept_count
10          4              22               3
10          4              21               1
11          2              20               2

Tried with following code but it doesn't count seperately for both columns even though applied group by employee_master.dept_id, employee_master.sub_dept_id. Please note that there is only 1 column common between both table that is emp_code.

SELECT p.emp_code
     , e.emp_code
     , COUNT(e.dept_id) dept_id_count
     , COUNT(e.sub_dept_id) sub_dept_id_count
  FROM punching_data_table p
  LEFT 
  JOIN employee_master e
    ON e.emp_code = p.emp_code
 GROUP 
    BY e.dept_id
     , e.sub_dept_id

Any help on the subject with explanation will be highly appreciated.

Try this query

SELECT emp_code, MAX(dept_id_count) as dept_id_count,  MAX(sub_dept_id_count) as sub_dept_id_count
FROM
(SELECT p.emp_code  , COUNT(e.dept_id) dept_id_count, 0 as sub_dept_id_count
FROM punching_data_table p
LEFT JOIN employee_master e ON e.emp_code = p.emp_code
GROUP BY e.dept_id
UNION
SELECT p.emp_code, 0 as dept_id_count, COUNT(e.sub_dept_id) sub_dept_id_count
FROM punching_data_table p
LEFT JOIN employee_master e ON e.emp_code = p.emp_code
GROUP BY e.sub_dept_id) as subQuery
GROUP BY emp_code

This query ( SQLFiddle ) will give you the output that you specify:

SELECT em1.dept_id, em2.dept_count, em1.sub_dept_id, COUNT(em1.sub_dept_id) AS sub_dept_count
FROM employee_master em1
JOIN (SELECT dept_id, COUNT(dept_id) as dept_count 
      FROM employee_master e
      JOIN punching_data_table p
      ON e.emp_code = p.emp_code
      GROUP BY dept_id) em2
ON em1.dept_id = em2.dept_id
WHERE EXISTS (SELECT * FROM punching_data_table pdt WHERE pdt.emp_code = em1.emp_code)
GROUP BY dept_id, sub_dept_id

Output:

dept_id     dept_count  sub_dept_id     sub_dept_count
10          4           21              1
10          4           22              3
11          2           20              2

If you have a department names table eg

CREATE TABLE dept_master (dept_id INT, dept_name VARCHAR(20));

INSERT INTO dept_master VALUES
(10, 'Department 10'),
(11, 'Department 11');

You can join that as well using this query ( SQLFiddle ):

SELECT d.dept_name, em2.dept_count, em1.sub_dept_id, COUNT(em1.sub_dept_id) AS sub_dept_count
FROM employee_master em1
JOIN (SELECT dept_id, COUNT(dept_id) as dept_count 
      FROM employee_master e
      JOIN punching_data_table p
      ON e.emp_code = p.emp_code
      GROUP BY dept_id) em2
ON em1.dept_id = em2.dept_id
JOIN dept_master d on d.dept_id = em1.dept_id
WHERE EXISTS (SELECT * FROM punching_data_table pdt WHERE pdt.emp_code = em1.emp_code)
GROUP BY d.dept_id, sub_dept_id

And then get department names in the output instead of ids:

dept_name       dept_count  sub_dept_id     sub_dept_count
Department 10   4           21              1
Department 10   4           22              3
Department 11   2           20              2

There are some things which are not clear in your question for example do you want distinct employees or just a occurrences of employees, what happens if an employee does not exist in punching_data. I have made some assumptions in this answer but the crux of it is that you create 2 sub queries and join them on dept id which will force a 1 to many join

so given

drop table if exists employee_master,punching_data_table;

create table employee_master
(emp_code int,         dept_id  int,        sub_dept_id int);
insert into employee_master values
(1       ,            10   ,               22),
(2       ,            11   ,               20),
(3       ,            10   ,               22),
(4       ,            10   ,               22),
(5       ,            11   ,               20),
(6       ,            10   ,               21 ),
(7       ,            10   ,               21);

create table punching_data_table(emp_code int);
insert into punching_data_table values          
(1),                   
(2),                 
(3),                   
(4) ,                  
(5),
(6);

select a.dept_id,a.empcodes,s.sub_dept_id,s.empcodes from
(
select  dept_id ,count(distinct emp_code) empcodes
from employee_master
where emp_code in (select emp_code from punching_data_table)
group by dept_id
) a

join

(select dept_id , sub_dept_id, count(distinct emp_code)  empcodes
from employee_master
where emp_code in (select emp_code from punching_data_table)
group by dept_id,sub_dept_id) s
on s.dept_id = a.dept_id
order by a.dept_id,s.sub_dept_id

Result

+---------+----------+-------------+----------+
| dept_id | empcodes | sub_dept_id | empcodes |
+---------+----------+-------------+----------+
|      10 |        4 |          21 |        1 |
|      10 |        4 |          22 |        3 |
|      11 |        2 |          20 |        2 |
+---------+----------+-------------+----------+
3 rows in set (0.00 sec)

This result can be achieved without punching_data_table

SELECT t1.dept_id, 
       t2.sub_dept_id, 
       t1.count_dept, 
       t2.count_sub 
FROM   (SELECT dept_id, 
               sub_dept_id, 
               Count(dept_id) AS count_dept 
        FROM   employee_master 
        GROUP  BY dept_id)t1 
       LEFT JOIN (SELECT sub_dept_id, 
                         dept_id, 
                         Count(sub_dept_id) AS count_sub 
                  FROM   employee_master 
                  GROUP  BY sub_dept_id)t2 
              ON t1.dept_id = t2.dept_id

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