用于获取员工出勤的SQL查询

时间:2015-03-17 05:31:23

标签: sql oracle

我需要在员工表上编写查询来获取员工ID和员工的员工。他出席了多少天缺席&给定日期范围的半天。

Employee            
AID EmpID   Status     Date
1   10      Present   17-03-2015
2   10      Absent    18-03-2015
3   10      HalfDay   19-03-2015
4   10      Present   20-03-2015
5   11      Present   21-03-2015
6   11      Absent    22-03-2015
7   11      HalfDay   23-03-2015

预期输出将是:

EmpID   Present Absent  HalfDay
10       2      1        1
11       1      1        1

你能帮我解决一下Sql查询吗?

这是我试过的查询

SELECT EMP.EMPID,
(CASE WHEN EMP.STATUS = 'Present' THEN COUNT(STATUS) ELSE 0 END) Pres,
(CASE WHEN EMP.STATUS = 'Absent' THEN COUNT(STATUS) ELSE 0 END) ABSENT, 
(CASE WHEN emp.status = 'HalfDay' THEN Count(status) ELSE 0 END) HalfDay
FROM EMPLOYEE EMP GROUP BY emp.empid

2 个答案:

答案 0 :(得分:4)

COUNT()函数测试值是否为NOT NULL。因此,它总是会增加CASE语句的两面,如下所示:

COUNT(CASE Status WHEN 'Present' THEN 1 ELSE 0) AS Present 

所以我们需要使用SUM()...

select empid,
    sum(case when status='Present' then 1 else 0 end) present_tot,
    sum(case when status='Absent' then 1 else 0 end)  absent_tot,
    sum(case when status='HalfDay' then 1 else 0 end) halfday_tot
from employee
group by empid
order by empid
/

...或使用带有NULL else子句的COUNT()。两者产生相同的输出,也许这个更清楚:

SQL> select empid,
  2      count(case when status='Present' then 1 end) present_tot,
  3      count(case when status='Absent' then 1 end)  absent_tot,
  4      count(case when status='HalfDay' then 1 end) halfday_tot
  5  from employee
  6  group by empid
  7  order by empid 
  8  /

     EMPID PRESENT_TOT ABSENT_TOT HALFDAY_TOT
---------- ----------- ---------- -----------
        10           2          1           1
        11           1          1           1

SQL>

请注意,我们需要使用ORDER BY来保证结果集的顺序。 Oracle为10g中的聚合引入了散列优化,这意味着GROUP BY很少返回可预测的排序顺序。

答案 1 :(得分:0)

将0替换为null,因为它也会计入并添加了日期范围的where子句,请查看以下示例:

select empID,
count(case when status='Present' then 1 else null end) Present_Days,
count(case when status='Absent' then 1 else null end)  Absent_Days,
count(case when status='HalfDay' then 1 else null end) HalfDays
from Employee 
where date >= to_date('17mar2015') and date <= to_date('23mar2015')
group by empID