Top N earliest punched in Employees across departments in a month
Question
Find two of the earliest punched in Employees across departments in a month The dataset.
Id EmpName EmpPunchInTime EmpDept
1 Dharma 26-JAN-2018 08:45 Engineering
2 Gumpina 26-JAN-2018 08:46 Finance
3 Kumar 26-JAN-2018 08:47 HR
4 Kamal 26-JAN-2018 08:48 Engineering
5 Muruges 26-JAN-2018 08:49 Finance
6 Gumpina 25-JAN-2018 09:01 Finance
7 Kumar 25-JAN-2018 08:42 HR
8 Biju 25-JAN-2018 08:40 Engineering
9 Divya 25-JAN-2018 08:49 HR
10 Vali 24-JAN-2018 08:52 Engineering
The expected output is,
Id EmpName EmpPunchInTime EmpDept
8 Biju 25-JAN-2018 08:40 Engineering
1 Dharma 26-JAN-2018 08:45 Engineering
2 Gumpina 26-JAN-2018 08:46 Finance
5 Muruges 26-JAN-2018 08:49 Finance
7 Kumar 25-JAN-2018 08:42 HR
9 Divya 25-JAN-2018 08:49 HR
FYI I the query which I used
SELECT *
FROM (SELECT *
,DENSE_RANK() OVER ( PARTITION BY EmpDept ORDER BY EmpPunchInTime) RANK
FROM EMPLOYEE_PUNCH) emp_pun
WHERE RANK <= 2
I have tried to solve by using dense rank(partition by EmpDept, order by EmpPunchInTime) but am not seeing desired results.
Note: If the same employee in a department punches early in most of the days(like Kumar of HR dept here in this dataset) then pick the earliest date among his dates and the employee who punches next to him.
Solution
It seems to me the specification failed to mention that the ordering should be done using only the hour and minute parts of the date.
The below returns the expected output.
with data as
(
select 1 as id, 'Dharma' as empname, to_date('26-JAN-2018 08:45', 'DD-MON-YYYY HH24:MI') as emppunchintime, 'Engineering' as empdept from dual union all
select 2 , 'Gumpina', to_date('26-JAN-2018 08:46', 'DD-MON-YYYY HH24:MI'), 'Finance' from dual union all
select 3 , 'Kumar', to_date('26-JAN-2018 08:47', 'DD-MON-YYYY HH24:MI'), 'HR' from dual union all
select 4 , 'Kamal' , to_date('26-JAN-2018 08:48', 'DD-MON-YYYY HH24:MI'), 'Engineering' from dual union all
select 5 , 'Muruges', to_date('26-JAN-2018 08:49', 'DD-MON-YYYY HH24:MI'), 'Finance' from dual union all
select 6 , 'Gumpina', to_date('25-JAN-2018 09:01', 'DD-MON-YYYY HH24:MI'), 'Finance' from dual union all
select 7 , 'Kumar', to_date('25-JAN-2018 08:42', 'DD-MON-YYYY HH24:MI'), 'HR' from dual union all
select 8 , 'Biju', to_date('25-JAN-2018 08:40', 'DD-MON-YYYY HH24:MI'), 'Engineering' from dual union all
select 9 , 'Divya', to_date('25-JAN-2018 08:49', 'DD-MON-YYYY HH24:MI'), 'HR' from dual union all
select 10, 'Vali', to_date('24-JAN-2018 08:52', 'DD-MON-YYYY HH24:MI'), 'Engineering' from dual
)
select f.id, f.empname, f.emppunchintime, f.empdept from
(
select e.*, row_number() over (partition by e.empdept order by to_char(e.emppunchintime, 'HH24:MI')) as rn2 from
(
select d.*, row_number() over (partition by d.empname order by to_char(d.emppunchintime, 'HH24:MI')) as rn from data d
) e
where e.rn = 1
) f
where f.rn2 <= 2
order by f.empdept, f.emppunchintime;
Output:
ID EMPNAME EMPPUNCHINTIME EMPDEPT
---------- ------- ----------------- -----------
8 Biju 25-JAN-2018 08:40 Engineering
1 Dharma 26-JAN-2018 08:45 Engineering
2 Gumpina 26-JAN-2018 08:46 Finance
5 Muruges 26-JAN-2018 08:49 Finance
7 Kumar 25-JAN-2018 08:42 HR
9 Divya 25-JAN-2018 08:49 HR
Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange