2012-12-09 43 views
0

1. emp_ot 表使用定義哪些僱員可以將特定時期MySQL的插入上重複鍵更新的選擇數據使用相關的子查詢與計算字段

2. daily_attend內做 的OT小時最大量描述什麼是真正發生

3.my表縮寫形式如下

mysql> select punchDate,empNO,ot from daily_attend; 
+------------+--------+----------+ 
| punchDate | empNO | ot  | 
+------------+--------+----------+ 
| 2012-02-20 | 00| 02:00:00 | 
| 2012-02-02 | 00| 01:00:00 | 
| 2012-02-01 | 000126 | 01:00:00 | 
| 2012-02-01 | 00| 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 | 00| 2012-02-01 | 2012-02-10 | 02:00:00 | 
|  2 |   02 | 00| 2012-02-20 | 2012-02-25 | 03:00:00 | 
|  3 |   02 | 000126 | 2012-02-01 | 2012-01-10 | 02:00:00 | 
|  4 |   03 | 00| 2012-03-01 | 2012-03-10 | 05:00:00 | 
+----------+-------------+--------+------------+------------+----------+ 
4 rows in set (0.00 sec) 

4.here我想更新emp_ot.workedOt知道有多少逾時 已根據各工作permitId由員工

例如:

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

5.i'm使用MySQL事件其中每天在00:00:01驅動的那個 因爲表應該會自動更新而不會搞亂舊數據

6.my試試如下:

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.i懷疑有壞表加入,實際上我不想 插入部分,如何只使用更新部分?

8.請幫助我糾正這些事情。謝謝大家。

+0

在您的示例數據中,''dateTo ='2012-01-10'' for permitId = 3'出錯了?它在*同一記錄的'dayFrom ='2012-02-01''之前*並且在計算列中給出了連接中的零值,而不是您示例中顯示的'01:00:00'輸出。 – eggyal

+0

我的榜樣不是真實的。我期待這樣的結果。 另外兩個表是真實的,但以排序的形式存在更多的列對這種情況不感興趣。在emp_ot表中沒有錯誤。 permitId = 3被分配給empN0 = 000126,並且permitId = 1被分配給empN0 = 000123那些被分開的東西。雖然我給出了一個示例sql代碼(我的嘗試)也不要依賴它。 我主要期望得到「每個員工的每個permitId下工作了多少小時」,並且我想將這些數據更新到emp_ot.workedOt列 –

回答

0
  1. 我使用它在每天的驅動,在該00:00:01不搞亂舊的數據

    你有沒有考慮使用triggers因爲表應該是自動更新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

+0

首先感謝您介紹sqlfiddle。 emp_ot.permitId是INSERT部分中錯過的一個。實際上,我想更新emp_ot.workedOt,但在您的情況下,您已將其完成到 emp_ot.permiOt,'emp_ot.permiOt'是員工參加工作之前分配的一個因此initialy i put當emp_ot.workedOt列中的所有值都爲'00:00:00'時,系統的員工將捕獲他們的記錄並每日將其重新記錄到daily_attend表中。此後,該事件應該被觸發並將daily_attend.ot加到emp_ot.workedOt列中考慮到daily_attend,它放棄了emp_ot.permitId。puncDate –

+0

sory爲我醜陋的英文打字 –