mysql复杂查询月报

时间:2013-05-16 10:51:33

标签: mysql group-by subquery

员工在启动新任务时在下表中输入 来自家庭或办公室

[tablename=CHECK]
c_id   c_sdate                c_emp       c_task
-------------------------------------------------
1     2013-05-01 01:01:00       1           26    //date 01 from home-----
2     2013-05-01 08:11:00       1           27    //date 01 from office--- Present

3     2013-05-02 03:41:00       1           28    //date 02 from home---
4     2013-05-02 09:12:00       1           29    //date 02 from office-
5     2013-05-02 22:32:00       1           30    //date 02 from home---Present

6     2013-05-03 01:43:00       1           31    //date 03 from home
7     2013-06-03 23:25:00       1           32    //date 03 from home----------Homework

8     2013-06-03 02:15:00       2           33    //other employee
如果有一个或多个记录,其中时间在上午8点到晚上8点之间,那么雇员将被视为在场。

如果有一个或多个记录,其中时间不是在上午8点到晚上8点之间,并且当天没有出现,则员工将被视为workFromHome    注意:如果在上午8点到晚上8点之间有任何记录时间,请不要计算一天workWorkRromHome(意味着workingRromHome仅在当天没有重新发送时计算)

  

我想显示员工的月度报告,例如。例如,c_emp = 1月份。五   在1个查询中像这样

c_emp  presentCount   HW_Count
  1       3             1   

或分开查询1

c_emp  presentCount  
  1       3

和查询2

c_emp   HW_Count
  1        1     

我曾尝试过计算当前正常工作

select count(distinct(date_format(c_sdate,'%e'))) as count 
from ita_check
where date_format(c_sdate,'%m')=5 
and c_emp=1 
and date_format(c_sdate,'%H%i')>=800
and date_format(c_sdate,'%H%i')<=2000

并且计算来自家庭的错误计数

select count(distinct(date_format(c_sdate,'%e'))) as count 
from ita_check
where date_format(c_sdate,'%m')=5
and c_eid=1
and c_id not in (
   select c_id 
   from ita_check
   where date_format(c_sdate,'%m')=5 
   and c_eid=1
   and (date_format(c_sdate,'%H%i')<=800 or date_format(c_sdate,'%H%i')>=2000)
)
and date_format(c_sdate,'%H%i')<800
or date_format(c_sdate,'%H%i')>2000

在上面查询计数工作 子查询返回1和2 而外部消除c_id = 2但不消除c_id = 1

1 个答案:

答案 0 :(得分:4)

尝试此查询

SELECT c_emp, 
sum(if(cnt>=1,1,0)) as Office, 
count(*)-sum(if(cnt>=1,1,0)) as WFH   from (
select c_emp, Date(c_sdate),
sum(if(c_sdate BETWEEN Date(c_sdate) + interval 8 hour 
       AND Date(c_sdate) + interval 20 hour, 1, 0)) as cnt
from table1
group by c_emp, Date(c_sdate)) tmp
group by c_emp

SQL FIDDLE

| C_EMP | OFFICE | WFH |
------------------------
|     1 |      2 |   2 |
|     2 |      0 |   1 |

月度报告

SELECT c_emp, date_format(c_date, '%c %Y') as Mnth,
sum(if(cnt>=1,1,0)) as Office, 
count(*)-sum(if(cnt>=1,1,0)) as WFH   from (
select c_emp, Date(c_sdate) as c_date,
sum(if(c_sdate BETWEEN Date(c_sdate) + interval 8 hour 
       AND Date(c_sdate) + interval 20 hour, 1, 0)) as cnt
from table1
group by c_emp, Date(c_sdate)) tmp
group by c_emp,Mnth 

SQL FIDDLE

| C_EMP |   MNTH | OFFICE | WFH |
---------------------------------
|     1 | 5 2013 |      2 |   1 |
|     1 | 6 2013 |      0 |   1 |
|     2 | 6 2013 |      0 |   1 |