员工整体出勤查询

时间:2012-02-18 10:20:47

标签: mysql subquery case

我很长时间都没有遇到这个问题。虽然你会发现这是一个很大的问题,但它不是............

我有以下表格,有虚拟数据,所以你也可以试试。

     users Table with Columns

        emp_id  emp_Name  Joining_Date         state_id
          1       Lauren  11-07-2011           123         
          2       John    01-08-2012           234
          3       Smith   02-09-2011           234
____________________________________________________    
CREATE TABLE users 
( emp_id int
, emp_Name varchar(20)
, Joining_Date DATE 
, state_id int 
);

INSERT INTO users (emp_id, emp_Name, Joining_Date, state_id) 
VALUES 
  (1, 'John',  '2011-08-10', 123) ,
  (2, 'Smith', '2011-09-11', 234) ; 

__________________________________________________________________
       cl_doctor_call Table

        Subject Call_Date     call_Done_By(emp_id)
        Call       15-01-2012      1
        CA        21-02-2012       2
___________________________________________________________________     
CREATE TABLE cl_doctor_call 
( Subject  VARCHAR(10)
, Call_Date DATE
, call_Done_By INT 
) ;

INSERT INTO cl_doctor_call (Subject, Call_Date,call_Done_By) 
VALUES 
  ('sub1', '2011-08-15', 1) ,
  ('sub2', '2011-09-16', 2) ;
___________________________________________________________________

        cl_ chemist Table

        Subject       Call_Date     call_Done_By(emp_id)
        Chemist       1-02-2012              2
        Texo          21-03-2012             1

____________________________________________________________________________________
CREATE TABLE cl_chemist ( Subject  VARCHAR(10),  Call_Date DATE, call_Done_By INT   );

INSERT INTO cl_chemist (Subject, Call_Date,call_Done_By) VALUES ('sub3','2011-08-19',2),('sub5','2011-09-25',1);

___________________________________________________________
        cl_Stock Table

        Subject  Call_Date     call_Done_By(emp_id)
        Sub1     1-02-2012            1
        Sub2     21-03-2012           3
____________________________________________________________
CREATE TABLE cl_Stock 
( Subject  VARCHAR(10)
, Call_Date DATE
, call_Done_By INT
);

INSERT INTO cl_Stock (Subject, Call_Date,call_Done_By) 
VALUES 
  ('ABC',  '2011-10-13', 1) , 
  ('sub5', '2011-11-17', 2) ;

______________________________________________________    
        Meetings Table

        Subject Meeting_Date   call_Done_By(emp_id)
        Sub1     11-02-2012          1
        Sub2     23-03-2012          2    _____________________________________________________________________________________       
CREATE TABLE Meetings (   Subject  VARCHAR(10),   meet_Date DATE, meet_Done_By INT    );

INSERT INTO Meetings (Subject, meet_Date,meet_Done_By)
VALUES 
  ('Planning','2011-11-01',2),
  ('Deploy','2011-12-15',1);

______________________________________________________________________________________
        Leave Table
        Subject     from_Date         to_date       Requested_By(emp_id)   status
        Sub1        01-02-2012       03-02-2012           2               Declined
        Sub2       21-03-2012        22-03-2012           1               Approved

        Holiday Table

        Holiday_Name              Holiday_Date      States_Id
        New Year                  01-01-2012            123

       Independence Day          15-08-2012            234
______________________________________________________________________________________
CREATE TABLE Holiday (    Holiday_Name  VARCHAR(10),Holiday_Date DATE,   State_Id_c INT     );


INSERT INTO Holiday (Holiday_Name,Holiday_Date,State_Id_c) VALUES ('NEW_YEAR','2012-01-01',123), ('CHRISHMAS','2011-12-25',234);
______________________________________________________________________________________    
    Replace with date
    for stock='Y'
    for chemist='Y'
    for doctor='Y'
    for leave='L'
    for Sunday='S'
    for meeting ='M'
    for Holiday='H'

Hope so still you are with me.

 Now Admin will select 'month' and 'year' and according to that attendance report for 

 employee will displayed.

        Output :
        Employee     Year       Month     1 2 3 4 5 6 7.... for all 31 days
        John         2011       Nov       Y Y Y H Y L S....
        Smith        2011       Nov       Y Y Y H Y M S.....
          .           .          .        ................ 
          .           .          .        ................
        &so on      &so on     &so on     & so on      

这里输出1,2,3 ....是一个月0-31的天数,我们可以使用'case'

考虑员工是否在当天出现,其状态为“Y”,如果他在休假时显示其状态为“L”;如果假期节目'H'有星期天节目状态'S',等等。

所以基本上我想写一个查询来检索所有这些细节。

所以请告诉我这里的方法,如何通过查询或程序显示此出勤报告。

到目前为止我已经尝试过了.....

DELIMITER $$

USE `leosatyen_claris`$$

DROP PROCEDURE IF EXISTS `Test`$$

CREATE DEFINER=`leosatyen_claris`@`%` PROCEDURE `Test`(IN month_last_date DATE)
BEGIN
SELECT 
users.id AS Id,
users.first_name AS Employee,
CASE MAX(CASE WHEN DATE_FORMAT(main.cdate,'%d')='01' THEN main.task
              WHEN DATE_FORMAT(DATE_ADD(month_last_date, INTERVAL 1 DAY),'%W')='SUNDAY' THEN 0
              WHEN main.cdate IS NULL THEN -1
         ELSE -2 END)
     WHEN -1 THEN 'NA'
     WHEN  0 THEN 'S'
     WHEN  1 THEN 'Y'
     WHEN  2 THEN 'C'
     WHEN  3 THEN 'S1'
     WHEN  4 THEN 'P'
     WHEN  5 THEN 'M'

END Day1,
CASE MAX(CASE WHEN DATE_FORMAT(main.cdate,'%d')='02' THEN main.task
              WHEN DATE_FORMAT(DATE_ADD(month_last_date, INTERVAL 2 DAY),'%W') ='SUNDAY' THEN 0
              WHEN main.cdate IS NULL THEN -1
         ELSE -2 END)
     WHEN -1 THEN 'NA'
     WHEN  0 THEN 'S'
      WHEN  1 THEN 'Y'
      WHEN  2 THEN 'C'
      WHEN  3 THEN 'S1'
      WHEN  4 THEN 'P'
      WHEN  5 THEN 'M'

END Day2,
.
.
. ## UP TO 31 DAYS

CASE MAX(CASE WHEN DATE_FORMAT(main.cdate,'%d')='31' THEN main.task
              WHEN DATE_FORMAT(DATE_ADD(month_last_date, INTERVAL 31 DAY),'%W')='SUNDAY' THEN 0
              WHEN main.cdate IS NULL THEN -1
         ELSE -2 END)
     WHEN -1 THEN 'NA'
     WHEN  0 THEN 'S'
     WHEN  1 THEN 'Y'
     WHEN  2 THEN 'C'
     WHEN  3 THEN 'S1'
     WHEN  4 THEN 'P'
     WHEN  5 THEN 'M'
END Day31 
FROM
users  
LEFT JOIN
(
SELECT DATE_FORMAT(cl_doctor_call.date_entered,'%Y-%m-%d')AS cdate,
  cl_doctor_call.created_by  AS emp,
  1     task     
  FROM 
  cl_doctor_call  
  WHERE 
  DATE_FORMAT(cl_doctor_call.date_entered,'%Y-%m-%d')>month_last_date AND
  DATE_FORMAT(cl_doctor_call.date_entered,'%Y-%m-%d')<=DATE_ADD(month_last_date, INTERVAL 30 DAY)

  UNION ALL
  SELECT 
  DATE_FORMAT(cl_chemist_call.date_entered,'%Y-%m-%d') AS  cdate,
  cl_chemist_call.created_by AS emp,
  2    task     
  FROM 
  cl_chemist_call
  WHERE 
  DATE_FORMAT(cl_chemist_call.date_entered,'%Y-%m-%d')>month_last_date AND
  DATE_FORMAT(cl_chemist_call.date_entered,'%Y-%m-%d')<=DATE_ADD(month_last_date, INTERVAL 30 DAY)

  UNION ALL
  SELECT 
  DATE_FORMAT(cl_stockist_call_cstm.calldate_c,'%Y-%m-%d') AS cdate,
  cl_stockist_call.created_by AS emp,
  3         task
  FROM 
  cl_stockist_call LEFT JOIN cl_stockist_call_cstm
  ON cl_stockist_call.id=cl_stockist_call_cstm.id_c
  WHERE 
  DATE_FORMAT(cl_stockist_call_cstm.calldate_c,'%Y-%m-%d')> month_last_date AND
  DATE_FORMAT(cl_stockist_call_cstm.calldate_c,'%Y-%m-%d')<=DATE_ADD(month_last_date, INTERVAL 30 DAY)

  UNION ALL
  SELECT DATE_FORMAT(cl_product_pramotional_call.date_entered,'%Y-%m-%d') AS cdate,
  cl_product_pramotional_call.created_by AS emp,
  4       task
  FROM cl_product_pramotional_call
  WHERE  
  DATE_FORMAT(cl_product_pramotional_call.date_entered,'%Y-%m-%d')>month_last_date AND
  DATE_FORMAT(cl_product_pramotional_call.date_entered,'%Y-%m-%d')<=DATE_ADD(month_last_date, INTERVAL 30 DAY)

  UNION ALL

  SELECT DATE_FORMAT(meetings.date_start,'%Y-%m-%d') AS cdate,
  meetings.created_by AS emp,
  5        task
  FROM meetings
  WHERE  
  DATE_FORMAT(meetings.date_start,'%Y-%m-%d')> month_last_date AND
  DATE_FORMAT(meetings.date_start,'%Y-%m-%d') <= DATE_ADD(month_last_date, INTERVAL 30 DAY)

 )AS main 
 ON main.emp = users.id 
 WHERE DATE_FORMAT(users.date_entered,'%Y-%m-%d')<= month_last_date
 GROUP BY users.id ;
 END$$

DELIMITER ;

我在这个月的所有星期天和所有客户电话,如Doctor_call, 化学家电话,库存商电话和会议参赛作品正确。

现在我只需要添加'Leave'和Holiday Entries。那么任何人都可以协助我实现假期并离开我现有的程序吗?

任何建议对我都有帮助....

1 个答案:

答案 0 :(得分:0)

最后,我获得了出勤报告的答案。

我们需要执行这个冗长的存储过程来获得所有员工的月度出勤率。

要执行此程序,我们需要将IN参数作为上个月的最后一个日期传递,就像我们需要查看2011年12月的出勤报告一样,通过'2011-11-30'AS IN参数。

DELIMITER $$

USE `Sample`$$

DROP PROCEDURE IF EXISTS `Test`$$

CREATE DEFINER=`Sample`@`%` PROCEDURE `Test`(IN month_last_date DATE)
BEGIN
SELECT 
users.id AS Id,DATE_FORMAT(month_last_date,'%Y')AS YEAR,DATE_FORMAT(month_last_date,'%M')AS MONTH,
CONCAT(users.first_name,users.last_name) AS Employee,cl_territories.name AS Territory,
CASE MAX(CASE WHEN DATE_FORMAT(main.cdate,'%d')='01' THEN main.task
              WHEN DATE_FORMAT(DATE_ADD(month_last_date, INTERVAL 1 DAY),'%W')='SUNDAY' THEN 0
              WHEN main.cdate IS NULL THEN -1
         ELSE -2 END)
     WHEN -1 THEN 'NA'
     WHEN  0 THEN 'S'
     WHEN  1 THEN 'Y'
     WHEN  2 THEN 'C'
     WHEN  3 THEN 'S1'
     WHEN  4 THEN 'P'
     WHEN  5 THEN 'M'
     WHEN  6 THEN 'H'
     WHEN  7 THEN 'L'
END Day1,
CASE MAX(CASE WHEN DATE_FORMAT(main.cdate,'%d')='02' THEN main.task
              WHEN DATE_FORMAT(DATE_ADD(month_last_date, INTERVAL 2 DAY),'%W') ='SUNDAY' THEN 0
              WHEN main.cdate IS NULL THEN -1
         ELSE -2 END)
     WHEN -1 THEN 'NA'
     WHEN  0 THEN 'S'
      WHEN  1 THEN 'Y'
      WHEN  2 THEN 'C'
      WHEN  3 THEN 'S1'
      WHEN  4 THEN 'P'
      WHEN  5 THEN 'M'
      WHEN  6 THEN 'H'
      WHEN  7 THEN 'L'
END Day2,
.
.
. # upto 31 days

CASE MAX(CASE WHEN DATE_FORMAT(main.cdate,'%d')='31' THEN main.task
              WHEN DATE_FORMAT(DATE_ADD(month_last_date, INTERVAL 31 DAY),'%W')='SUNDAY' THEN 0
              WHEN main.cdate IS NULL THEN -1
         ELSE -2 END)
     WHEN -1 THEN 'NA'
     WHEN  0 THEN 'S'
     WHEN  1 THEN 'Y'
     WHEN  2 THEN 'C'
     WHEN  3 THEN 'S1'
     WHEN  4 THEN 'P'
     WHEN  5 THEN 'M'
     WHEN  6 THEN 'H'
     WHEN  7 THEN 'L'
END Day31
FROM
users  LEFT JOIN users_cstm
ON users.id=users_cstm.id_c
LEFT JOIN cl_territories
ON users_cstm.cl_territories_id1_c=cl_territories.id
LEFT JOIN
(
SELECT DATE_FORMAT(cl_doctor_call.date_entered,'%Y-%m-%d')AS cdate,
  cl_doctor_call.created_by  AS emp,
  1     task     
  FROM 
  cl_doctor_call  
  WHERE 
  DATE_FORMAT(cl_doctor_call.date_entered,'%Y-%m-%d')>month_last_date AND
  DATE_FORMAT(cl_doctor_call.date_entered,'%Y-%m-%d')<=DATE_ADD(month_last_date, INTERVAL 30 DAY)

  UNION ALL
  SELECT 
  DATE_FORMAT(cl_chemist_call.date_entered,'%Y-%m-%d') AS  cdate,
  cl_chemist_call.created_by AS emp,
  2    task     
  FROM 
  cl_chemist_call
  WHERE 
  DATE_FORMAT(cl_chemist_call.date_entered,'%Y-%m-%d')>month_last_date AND
  DATE_FORMAT(cl_chemist_call.date_entered,'%Y-%m-%d')<=DATE_ADD(month_last_date, INTERVAL 30 DAY)

  UNION ALL
  SELECT 
  DATE_FORMAT(cl_stockist_call_cstm.calldate_c,'%Y-%m-%d') AS cdate,
  cl_stockist_call.created_by AS emp,
  3         task
  FROM 
  cl_stockist_call LEFT JOIN cl_stockist_call_cstm
  ON cl_stockist_call.id=cl_stockist_call_cstm.id_c
  WHERE 
  DATE_FORMAT(cl_stockist_call_cstm.calldate_c,'%Y-%m-%d')> month_last_date AND
  DATE_FORMAT(cl_stockist_call_cstm.calldate_c,'%Y-%m-%d')<=DATE_ADD(month_last_date, INTERVAL 30 DAY)

  UNION ALL
  SELECT DATE_FORMAT(cl_product_pramotional_call.date_entered,'%Y-%m-%d') AS cdate,
  cl_product_pramotional_call.created_by AS emp,
  4       task
  FROM cl_product_pramotional_call
  WHERE  
  DATE_FORMAT(cl_product_pramotional_call.date_entered,'%Y-%m-%d')>month_last_date AND
  DATE_FORMAT(cl_product_pramotional_call.date_entered,'%Y-%m-%d')<=DATE_ADD(month_last_date, INTERVAL 30 DAY)

  UNION ALL

  SELECT DATE_FORMAT(meetings.date_start,'%Y-%m-%d') AS cdate,
  meetings.created_by AS emp,
  5        task
  FROM meetings
  WHERE  
  DATE_FORMAT(meetings.date_start,'%Y-%m-%d')> month_last_date AND
  DATE_FORMAT(meetings.date_start,'%Y-%m-%d') <= DATE_ADD(month_last_date, INTERVAL 30 DAY)

  UNION ALL
SELECT DATE_FORMAT(cl_holidays_structures.holiday_date,'%Y-%m-%d') AS cdate,
users.id AS emp,
6    task
FROM users LEFT JOIN users_cstm
ON users.id=users_cstm.id_c
LEFT JOIN cl_states
ON users_cstm.cl_states_id1_c=cl_states.id
LEFT JOIN cl_holidays_structures
ON cl_holidays_structures.cl_states_id_c=users_cstm.cl_states_id1_c
WHERE  
DATE_FORMAT(cl_holidays_structures.holiday_date,'%Y-%m-%d')> month_last_date AND
DATE_FORMAT(cl_holidays_structures.holiday_date,'%Y-%m-%d') <= DATE_ADD(month_last_date, INTERVAL 30 DAY)
UNION ALL
SELECT cl_leave_management_cstm.from_date_c+ INTERVAL td.days DAY cdate, 
users.id AS emp,
7    task
FROM
  cl_leave_management LEFT JOIN cl_leave_management_cstm
  ON cl_leave_management.id=cl_leave_management_cstm.id_c
LEFT JOIN users 
  ON cl_leave_management.created_by = users.id
JOIN temp_days td
  ON DATEDIFF(cl_leave_management_cstm.to_date_c, cl_leave_management_cstm.from_date_c) >= td.days
WHERE DATE_FORMAT(cl_leave_management_cstm.from_date_c,'%Y-%m-%d')> month_last_date AND
 DATE_FORMAT(cl_leave_management_cstm.from_date_c,'%Y-%m-%d')<=DATE_ADD(month_last_date, INTERVAL 30 DAY) AND
 cl_leave_management_cstm.status_c='Approved'

 )AS main 
 ON main.emp = users.id 
 WHERE DATE_FORMAT(users.date_entered,'%Y-%m-%d')<= month_last_date
 GROUP BY users.id ;
 END$$

DELIMITER ;

感谢所有指导我获得此结果的人。