I need to count the number of rows for each employee where the status = 9
and the date
is the same as other rows within that employee_id
where the status = 9
. I also want the employee_id
and count_all
, a count of all the rows for each employee.
Figuring out how to get the count_same_date_status_9
column is where I am stuck. These dates are made up just for the example so I dont want to put them explicitly into the query.
My table:
employee_id status date
1 9 10/19/2020
1 7 07/16/2001
1 9 10/19/2020
2 5 08/11/2011
2 9 12/25/2012
2 9 11/19/2013
3 5 06/05/2016
3 4 01/01/2021
4 9 02/15/2018
4 9 02/15/2018
4 9 02/15/2018
I want to return the following:
employee_id count_same_date_status_9 count_all
1 2 3
2 0 3
3 0 2
4 3 3
You can use:
SELECT employee_id,
MAX( CASE WHEN status = 9 AND cnt > 1 THEN cnt ELSE 0 END ) AS count_9,
SUM( cnt ) AS count_all
FROM (
SELECT employee_id,
status,
dt,
COUNT(*) AS cnt
FROM table_name
GROUP BY employee_id, status, dt
)
GROUP BY employee_id
ORDER BY employee_id;
Which, for your sample data:
CREATE TABLE table_name ( employee_id, status, dt ) AS
SELECT 1, 9, DATE '2020-10-19' FROM DUAL UNION ALL
SELECT 1, 7, DATE '2001-07-16' FROM DUAL UNION ALL
SELECT 1, 9, DATE '2020-10-19' FROM DUAL UNION ALL
SELECT 2, 5, DATE '2011-08-11' FROM DUAL UNION ALL
SELECT 2, 9, DATE '2012-12-25' FROM DUAL UNION ALL
SELECT 2, 9, DATE '2013-11-19' FROM DUAL UNION ALL
SELECT 3, 5, DATE '2016-06-05' FROM DUAL UNION ALL
SELECT 3, 4, DATE '2021-01-01' FROM DUAL UNION ALL
SELECT 4, 9, DATE '2018-02-15' FROM DUAL UNION ALL
SELECT 4, 9, DATE '2018-02-15' FROM DUAL UNION ALL
SELECT 4, 9, DATE '2018-02-15' FROM DUAL;
Outputs:
\nEMPLOYEE_ID | COUNT_9 | COUNT_ALL \n----------: | ------: | --------: \n 1 | 2 | 3 \n 2 | 0 | 3 \n 3 | 0 | 2 \n 4 | 3 | 3 \n
db<>fiddle here
The logic you want is a bit counter-intuitive, but I think you can do this with two levels of aggregation:
select employee_id,
case when max(cnt2) = 1 then 0 else max(cnt2) end count_same_date_status_9,
sum(cnt1) count_all
from (
select employee_id, dt, count(*) cnt1, sum(case when status = 9 then 1 else 0 end) cnt2
from mytable t
group by employee_id, dt
) t
group by employee_id
order by employee_id
EMPLOYEE_ID | COUNT_SAME_DATE_STATUS_9 | COUNT_ALL ----------: | -----------------------: | --------: 1 | 2 | 3 2 | 0 | 3 3 | 0 | 2 4 | 3 | 3
The result can be achieved with a simple group by, then a subquery to find the most status = 9
that occured on the same day.
WITH
employees (employee_id, status, status_date)
AS
(SELECT 1, 9, TO_DATE ('10/19/2020', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 1, 7, TO_DATE ('07/16/2001', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 1, 9, TO_DATE ('10/19/2020', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 2, 5, TO_DATE ('08/11/2011', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 2, 9, TO_DATE ('12/25/2012', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 2, 9, TO_DATE ('11/19/2013', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 3, 5, TO_DATE ('06/05/2016', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 3, 4, TO_DATE ('01/01/2021', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 4, 9, TO_DATE ('02/15/2018', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 4, 9, TO_DATE ('02/15/2018', 'MM/DD/YYYY') FROM DUAL
UNION ALL
SELECT 4, 9, TO_DATE ('02/15/2018', 'MM/DD/YYYY') FROM DUAL)
SELECT employee_id,
NVL ((SELECT MAX (count_9)
FROM ( SELECT employee_id, status_date, COUNT (*) AS count_9
FROM employees e2
WHERE e2.status = 9 AND e2.employee_id = o.employee_id
GROUP BY employee_id, status_date)
HAVING MAX (count_9) > 1),
0) AS count_same_date_status_9,
count_all
FROM ( SELECT employee_id, COUNT (*) AS count_all
FROM employees e1
GROUP BY employee_id) o
ORDER BY employee_id
EMPLOYEE_ID COUNT_SAME_DATE_STATUS_9 COUNT_ALL
______________ ___________________________ ____________
1 2 3
2 0 3
3 0 2
4 3 3
this might work for MSSQL;
select employee_id,sum(A),sum(B) from(
select employee_id,count(*) A ,0 B from TABLENAME group by employee_id,status
union all
select employee_id,0 A,count(*) B from TABLENAME group by employee_id,date
) C group by employee_id
Someone gave this answer then deleted it so I'm not sure who to give credit to, but this query seems to be working as intended and is pretty simple to read:
select employee_id, sum(case when status = 9 then 1 else 0 end) as count_same_date_status_9, count(*) as count_all
from table_name
group by employee_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.