2017-02-01 9 views
0

私は、従業員、私は従業員が労働時間に応じて、毎時稼ぐいるどのくらいの保存、別のテーブルの作業時間を記録する2つの表1(personal_work)を持っています。 従業員は、さまざまな時間率の作業時間に応じている可能性があります。MySQLの時間の計算時に

それが、結果は、MySQL内のクエリトラフ取得することはできますか?

は、として、テーブルwork_our作業があるのでしょうか私は、同じ従業員のために別のレコードから== time_toは決してありません取るtime_fromを取る必要がありますか?あなたはvalid_date_fromとvalid_date_toを無視すると

personal_work

id | work_date | time_from | time_to | personal_id 
1 | 2017-01-01 | 16:00:00 | 22:00:00 | 3 
2 | 2017-01-01 | 11:00:00 | 12:00:00 | 6 
3 | 2017-01-01 | 15:00:00 | 02:00:00 | 10 
4 | 2017-01-01 | 20:00:00 | 00:00:00 | 12 

work_hour

id | personal_id | valid_date_from | valid_date_to | time_from | time_to | amount 
1 |   3 | 2013-01-01  |   null | 07:00:00 | 23:00:00 | 5.55 
2 |   3 | 2013-01-01  |   null | 23:00:00 | 07:00:00 | 7.77 
3 |   6 | 2013-01-01  |   null | 07:00:00 | 23:00:00 | 8.88 
4 |   6 | 2013-01-01  |   null | 23:00:00 | 07:00:00 | 5.55 
5 |   10 | 2013-01-01  |   null | 07:00:00 | 23:00:00 | 7.00 
6 |   10 | 2013-01-01  |   null | 23:00:00 | 07:00:00 | 10.00 
7 |   12 | 2013-01-01  |   null | 07:00:00 | 23:00:00 | 4.56 
8 |   12 | 2013-01-01  |   null | 23:00:00 | 07:00:00 | 7.89 

結果

personal_id | period_from   | period_to   | paid 
      3 | 2017-01-01 07:00:00 | 2017-02-01 06:59:59 | 33.30 
      6 | 2017-01-01 07:00:00 | 2017-02-01 06:59:59 | 8.88 
     10 | 2017-01-01 07:00:00 | 2017-02-01 06:59:59 | 86.00 
     12 | 2017-01-01 07:00:00 | 2017-02-01 06:59:59 | 21.57 
+0

1)work_hour:なぜIDは常に1ですか? 2)「テーブルwork_our作業があるか、私はtime_toを取る取らなければならないとして、ウィルは決してありません==同じ従業員のために別のレコードからtime_from?」:それは明らかではない、より良いこの質問を説明します。 3)personal_workで行の別の例を追加し、それに応じて結果を変更します(personal_id 3を持つ結果に2つのレコードがありますか?) – Eugenio

+0

Personal_id 6は8.88を獲得している必要があります;) –

+0

@Eugenio was私によって障害が、それはあなたは正しい違う – nenad007

答えて

1

、あなたはこれを使用することができます。

SELECT lo1.personal_id, 

     ROUND(SUM((TIME_TO_SEC(TIMEDIFF(lo1.end_datetime, lo1.start_datetime))/3600 - 
     TIME_TO_SEC(IF(lo1.start_datetime < lo2.start_datetime,TIMEDIFF(lo2.start_datetime, lo1.start_datetime),0))/3600 - 
     TIME_TO_SEC(IF(lo1.end_datetime > lo2.end_datetime,TIMEDIFF(lo1.end_datetime, lo2.end_datetime),0))/3600) * amount), 2) AS to_pay 
FROM 
    (SELECT personal_id, 
      ADDTIME(work_date, time_from) AS start_datetime, 
      ADDTIME(IF(time_to > time_from, work_date, work_date + INTERVAL 1 DAY), time_to) AS end_datetime 
    FROM personal_work) AS lo1 
JOIN 
    (SELECT personal_id, 
      ADDTIME(work_date, time_from) AS start_datetime, 
      ADDTIME(IF(time_to > time_from, work_date, work_date + INTERVAL 1 DAY), time_to) AS end_datetime, 
      amount 
    FROM 
     (SELECT DISTINCT work_date 
      FROM personal_work 
      UNION SELECT max(work_date) + interval 1 DAY 
      FROM personal_work AS work_date) AS dates_table 
    JOIN work_hour) AS lo2 ON lo1.personal_id = lo2.personal_id 
AND (lo1.start_datetime BETWEEN lo2.start_datetime AND lo2.end_datetime 
    OR lo1.end_datetime BETWEEN lo2.start_datetime AND lo2.end_datetime) 
GROUP BY 1 
+0

優れたソリューションを寝なければなりません。 – nenad007

+0

ようこそ。サブクエリを見ると、2つの中間テーブルが作成されていることがわかります。あなたがそれらを見ると、データ構造をわずかに変更しただけです。このようにテーブルを変更することは意味があります。これにより、クエリを大幅に減らすことができます。 –