0

1.emp_ot表用于 定义员工在特定时期内可以做的最大ot hours

2. daily_attend描述实际发生的事情

3.我的表格缩短形式如下

mysql> select punchDate,empNO,ot from daily_attend;
+------------+--------+----------+
| punchDate  | empNO  | ot       |
+------------+--------+----------+
| 2012-02-20 | 000123 | 02:00:00 |
| 2012-02-02 | 000123 | 01:00:00 |
| 2012-02-01 | 000126 | 01:00:00 |
| 2012-02-01 | 000123 | 01:00:00 |
+------------+--------+----------+
4 rows in set (0.01 sec)

mysql> select permitId,permitMonth,empNo,dayFrom,dayTO,permitOt from 
emp_ot;
+----------+-------------+--------+------------+------------+----------+
| permitId | permitMonth | empNo  | dayFrom    | dayTO      | permitOt |
+----------+-------------+--------+------------+------------+----------+
|        1 |          02 | 000123 | 2012-02-01 | 2012-02-10 | 02:00:00 |
|        2 |          02 | 000123 | 2012-02-20 | 2012-02-25 | 03:00:00 |
|        3 |          02 | 000126 | 2012-02-01 | 2012-01-10 | 02:00:00 |
|        4 |          03 | 000123 | 2012-03-01 | 2012-03-10 | 05:00:00 |
+----------+-------------+--------+------------+------------+----------+
4 rows in set (0.00 sec) 

4.在这里我想更新emp_ot.workedOt以了解员工在每个permitId下工作了多少小时

前任:

+----------+------------+----------+----------+
| permitId |  empNo     | workedOt | permitOt |
+----------+----------+----------+----------+
|        1 |  000123    | 02:00:00 | 02:00:00 |
|        2 |  000123    | 02:00:00 | 03:00:00 |
|        3 |  000126    | 01:00:00 | 02:00:00 |
|        4 |  000123    | 00:00:00 | 05:00:00 |
+----------+------------+----------+----------+

5.我正在使用 mysql 事件,它在每天 00:00:01 驱动,因为表应该自动更新而不会弄乱旧数据

6.我的尝试如下:

    DROP EVENT IF EXISTS make_emp_ot;

    DELIMITER |



    CREATE EVENT make_emp_ot

        ON SCHEDULE EVERY 1 DAY STARTS 
TIMESTAMP(CURRENT_DATE,'00:00:01')

        DO

          BEGIN 

        INSERT INTO emp_ot( permitMonth,empNo, dayFrom, dayTo, workedOt)

             SELECT  o.permitId,EXTRACT(MONTH FROM CURRENT_DATE)AS 
permitMonth ,o.empNo,'','',(
               SELECT ifnull( SEC_TO_TIME(SUM(TIME_TO_SEC(d.ot))) 
,'00:00:00')  

               FROM  daily_attend d

               WHERE d.punchDate BETWEEN o.dayFrom  AND o.dayTo
               GROUP BY o.empNo)AS ot

             FROM emp_ot o

             LEFT JOIN daily_attend d on o.empNo=d.empNo

             WHERE o.permitMonth=EXTRACT(MONTH FROM CURRENT_DATE)
          ON DUPLICATE KEY UPDATE

          workedOt=VALUES(workedOt) ;
    END; |


    DELIMITER ;

7.我怀疑有坏表加入,实际上我不想插入部分,如何只使用更新部分?

8.请帮我纠正这些事情。谢谢大家。

4

1 回答 1

0
  1. 我正在使用每天 00:00:01 驱动的 mysql 事件,因为表应该自动更新而不会弄乱旧数据

    您是否考虑过使用触发器

  2. 我怀疑有坏表加入

    INSERT ... ON DUPLICATE KEY UPDATE你的说法有很多问题:

    • 您在该部分中仅指定了五列INSERT,但SELECT返回六列(我怀疑您不打算这样做SELECT permitId

    • 空字符串''不是插入dayFromdayTo列的有效日期文字(假设它们是 MySQL 的DATE类型);

    • 您的GROUP BY子查询内部没有多大意义,因为外部查询只需要一条记录:您应该将其记录集限制为匹配empNo并删除其GROUP BY子句(所有行将由聚合函数隐式分组);

    • 由于您有相关的子查询,因此在外部查询中加入表是不必要且错误的(但是,您可以通过使用这样的联接然后对外部查询进行分组,从而在没有相关子查询的情况下获得相同的结果,这将提高性能);

    • 目前尚不清楚您是否UNIQUE定义了适当的键以使ON DUPLICATE KEY UPDATE部件按预期运行。

    实际上我不想插入部分,如何只使用更新部分?

    使用UPDATE代替INSERT

    UPDATE emp_ot e
    SET    permitOt := (
             SELECT IFNULL(SEC_TO_TIME(SUM(TIME_TO_SEC(d.ot))),0)
             FROM   daily_attend d
             WHERE  d.empNo = e.empNo
                AND d.punchDate BETWEEN e.dayFrom AND e.dayTO
           )
    WHERE  permitMonth = EXTRACT(MONTH FROM CURRENT_DATE)
    

    sqlfiddle上查看。

于 2012-12-09T07:58:41.953 回答