0

私はお気に入りのプロジェクトとして個人のタイム カード システムを作成しています。毎日と 1 週間の時間の合計を除いて、すべてがうまくいっています。while ループを使用してデータベースから取得した 1 日の 4 つのパンチがあるとします。

[1] 2013-03-01 07:00:00 - IN - (FOR DAY)
[2] 2013-03-01 12:00:00 - OUT (TO LUNCH)
[3] 2013-03-01 12:30:00 - IN (FROM LUNCH)
[4] 2013-03-01 15:30:00 - OUT (FOR DAY)

私の質問は、現在の合計を作成して合計 8 時間を吐き出すにはどうすればよいですか? 私はこれについて何日も考えてきましたが、論理的な解決策は頭にありません。前もって感謝します!

4

1 に答える 1

2

おそらく、テーブルの構造を変更する必要があります。根底にある考え方は、開始時刻と終了時刻を必要とする作業期間の概念です。現在の構造では、その事実が 2 つの行に分割されています。代わりに 1 行を使用してください。

work_periods
time_in              time_out
--
2013-03-01 07:00:00  2013-03-01 12:00:00
2013-03-01 12:30:00  2013-03-01 15:30:00

このような表がある場合、timestampdiff() を使用して分単位の差を簡単に取得できます。

select time_in, time_out, 
    timestampdiff(minute, time_in, time_out) elapsed_time
from work_periods;

既存のテーブルから同じデータを返すことができます。これは一時的なアプローチとしてのみ行うべきだと思います。この種の構造は、"out" が欠落している "in" と "in" が欠落している "out" を識別することを困難にします。

create table work_periods (
  work_ts datetime not null,
  in_or_out varchar(5) not null,
  primary key (work_ts)
  );

insert into work_periods values
('2013-03-01 07:00:00', 'IN'),
('2013-03-01 12:00:00', 'OUT'),
('2013-03-01 12:30:00', 'IN'),
('2013-03-01 15:30:00', 'OUT');

各「イン」に付随する「アウト」は、「イン」よりも遅い最初の「アウト」です。

select wp1.work_ts time_in,
       (select min(wp2.work_ts) 
        from work_periods wp2
        where wp2.work_ts > wp1.work_ts
          and wp2.in_or_out = 'OUT') time_out
from work_periods wp1
where wp1.in_or_out = 'IN';

もし選択肢があれば、そうするだろう

  • その最後の SELECT ステートメントから更新可能なビューを構築し、
  • ビューを使用するようにアプリケーション コードを更新し、最後に
  • この回答の冒頭にあるビューをベーステーブルに置き換えます。
于 2013-03-01T15:55:48.370 に答える