4

私は従業員のタイムシートに取り組んでおり、以下は表です。部門の従業員には2つのシフトがありTech SupportNetwork つまり[ 8:00 AM to 2:00 PM ][ 1:00 PM to 7:00 PM ]

そして通常シフト[ 9:00 AM to 6:00 PM ]

今、私が遅刻と早退の報告を得ようとしていること。サーバー側のコードに関するロジックはほとんどありませんが、実行速度が非常に遅いです。だから私はデータベースからそれを作りたかった。

私がしていること

遅刻して早退する従業員のレポートを生成しています

アルゴリズム

  1. 従業員の開始時刻を見つける..それぞれの部署..とそれぞれのシフト
  2. 従業員部門がソフトウェアの場合は、1 時間シフトを行い、それ以外の場合は、日によって 2 時間シフトを行います。
  3. パンチイン時間とログアウト時間から..従業員のシフトを見つけます。
  4. 従業員のシフトが第 1 シフトの場合、intime を as08:00:00 AMおよび outtime を asとして使用します。01:00:00 PM
  5. 従業員のシフトが第 2 シフトの場合、intime を as02:00:00 PMおよび outtime を asとして使用します。07:00:00 PM
  6. 従業員のシフトが通常シフトの場合、intime を as08:55:00 AMおよび outtime を asとして使用します。06:00:00 PM

次に、そのlogin_timeとログを見つけます

テーブル

従業員

emp_id  |   emp_name    |   emp_dept
--------------------------------------
1       |   Billy J     |   1
2       |   Sarah k     |   2
3       |   Takashi M   |   3
4       |   Matsuzaka   |   2

デパートメント

dept_id |   dept_name
--------------------------
1       |   Software
2       |   Tech Support
3       |   Network

従業員_ログイン

emp_id  |   login_time          |   logout_time
----------------------------------------------------------
1       |   2013-02-18 19:10:42 |   2013-02-18 21:27:37
2       |   2013-02-18 19:38:59 |   2013-02-18 22:46:14
3       |   2013-02-18 15:13:53 |   2013-01-01 18:26:39
4       |   2013-01-01 08:41:40 |   2013-01-01 016:41:40

SQLクエリ、試してみましたが、少し不完全です..

SELECT e.emp_id, e.emp_name, d.dept_name,
CASE d.dept_name
    WHEN d.dept_name IN ('Software') THEN 
        @intime := '08:55:00 AM'
    ELSE
        @intime := '02:00:00 PM'

END AS `StartingTime`,
@entrytime := DATE_FORMAT(el.login_time, '%r%') AS `Entered into Office`
TIMEDIFF(@entryTime,@intime) `difference`,
IF(TIMEDIFF(@entryTime,@intime)<'00:00:00',NULL,TIMEDIFF(@entryTime,@intime)) AS `Delay`

FROM employees e
INNER JOIN department d ON d.dept_id = e.emp_dept
INNER JOIN employee_login el ON el.emp_id = e.emp_id
WHERE DATE_FORMAT(el.login_time, '%Y-%m-%d') BETWEEN '2013-06-01' AND '2013-06-26'
ORDER BY el.login_time DESC;
4

1 に答える 1

3

以下は、この新しい 単純化されたCASE Fiddleのコードですこれが古い CASE Fiddleです。
- 一部の列は実際には必要なく、必要に応じて削除できます。
-注意!部門の条件に合わせて設定する必要があるすべての列でCASEを使用する必要がありました。また、質問の冒頭に記載したタイミングを使用したことに注意してください。それらを変更したい場合は、すべての CASE ステートメントで変更することを忘れないでください。そうしないと、必要な結果が得られません。

SELECT e.emp_id, d.dept_name, e.emp_name,
CASE d.dept_name
    WHEN 'Tech Support' THEN '08:00:00'
    WHEN 'Network' THEN '13:00:00'
    ELSE '09:00:00'
END AS `StartingTime`,
CASE d.dept_name
    WHEN 'Tech Support' THEN '14:00:00'
    WHEN 'Network' THEN '19:00:00'
    ELSE '18:00:00'
END AS `EndingTime`,
TIME_FORMAT(el.login_time, '%T') AS `Entered_into_Office`,
TIME_FORMAT(el.logout_time, '%T') AS `Left_from_Office`,
CASE d.dept_name
    WHEN 'Tech Support' THEN 
        TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('08:00:00', '%T')), '%T')
    WHEN 'Network' THEN
        TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('13:00:00', '%T')), '%T')
    ELSE 
        TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('09:00:00', '%T')), '%T')
END AS `Time_in_diff`,
CASE d.dept_name
    WHEN 'Tech Support' THEN 
        TIME_FORMAT(TIMEDIFF(TIME_FORMAT('14:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T')
    WHEN 'Network' THEN
        TIME_FORMAT(TIMEDIFF(TIME_FORMAT('19:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T')
    ELSE
        TIME_FORMAT(TIMEDIFF(TIME_FORMAT('18:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T')
END AS `Time_out_diff`,
CASE d.dept_name
    WHEN 'Tech Support' THEN TIME_FORMAT(SEC_TO_TIME(
        TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('08:00:00', '%T')), '%T'))
       +TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT('14:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T'))), '%T')    
    WHEN 'Network' THEN TIME_FORMAT(SEC_TO_TIME(
        TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('13:00:00', '%T')), '%T'))
       +TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT('19:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T'))), '%T')
    ELSE TIME_FORMAT(SEC_TO_TIME(
        TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT(el.login_time, '%T'), TIME_FORMAT('09:00:00', '%T')), '%T'))
       +TIME_TO_SEC(TIME_FORMAT(TIMEDIFF(TIME_FORMAT('18:00:00', '%T'), TIME_FORMAT(el.logout_time, '%T')), '%T'))), '%T')    
END AS `Total_time_diff`
FROM employees e
INNER JOIN department d ON d.dept_id = e.emp_dept
INNER JOIN employee_login el ON el.emp_id = e.emp_id
WHERE DATE_FORMAT(el.login_time, '%Y-%m-%d') BETWEEN '2012-01-01' AND '2013-12-31'
HAVING Total_time_diff > 0;

以下は私の以前の解決策です:
このSQLFiddleでは、スコープに対して 4 つのクエリを作成しました。これは、1 つの部門に対するクエリです。CASE 条件は使用しませんでしたが、機能します。各タイムシフトに 1 つ、すべてのタイムシートのデータを取得する 1 つ。後で、この行を削除する必要がありました: UNIONが成功ORDER BY Time_in_diff DESC;するためにそれが役立つかどうか教えてください!これは、準備されたステートメントを使用したソリューションです。

于 2013-06-29T14:35:02.483 に答える