我需要在员工表上编写查询来获取员工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
答案 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