質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

2回答

2842閲覧

PHP MySQL タイムカード 特殊な例

Z-TALBO

総合スコア525

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2016/10/14 00:15

編集2016/10/14 01:03

タイムカードのシステムみたいのを、試行錯誤しながら行っております。
基本的に名前の選択して打刻の種類とかのInsertや、その後のUpdate、Delete、データを検索とかする用のSelectなどは動作できるようになっています。

ただし、現在のやり方は例えば、「出勤」というと、基本的にその日の内に一度しか打刻することはないものですが、そういうエラーチェックのようなのを飛ばしてただ、動作させるような感じにしています。

一応動作する形はできたので、そういう1日に一度しかないものは重複させないなどのチェックを入れていこうと思ったのですが、、、一点だけ、うちの中で特殊な例がある部分をどうするかで悩んでいます。

###とりあえず自分で考えたこと
タイムカードで一般的に押されるとしたら
「出勤」
「退勤」
「休入」
「休戻」
はあろうかと思います。
そして、基本的にはこれらは一日の内一度だけ押されるものであることの方が多いかと思います。

今やってるうちのやり方は、名前の選択と打刻する種別も選択して送信します。
送信ボタン自体で振分とかではありません。
これは、一回に複数人分を入れたりしたいということもあるのとその複数人が全て出勤ではない場合などがある為です。

チェック方法としては、
○○さん出勤で送信があったら、DBで○○さん日時出勤でSELECTして、データが無ければInsert、データが有れば何もしないって感じで行けばとりあえずはできるのかな、、と思います。
これは他の退勤とかでも同じ考え方ができるかと思っています。

###特殊な例
上記の部分においても、実は考えることはまだあるかもしれませんが、、、
とりあえず本題はここの部分です。

今、うちでやっている中で「待機」という項目があります。あくまでも「休憩」ではない項目です。

外に出る仕事がメインの為、お客様の都合などで時間が空いたとか、そもそもそこの時間は仕事が無かったなどの時に発生するものです。
「待入」「待戻」というように項目は作成しています。
この「待機」は一日の内に複数回あると思われるので、特に上記のような制限は設けないのですが、、、

一つだけ条件があります。
1.「待入」14:00「待戻」14:29だった場合
「待機」0:29と計算できますが、この場合は0となります。
2.「待入」14:00「待戻」14:30だった場合
「待機」0:30と計算できますが、この場合は0:30となります。
ようは、30分以上から計算するけれど、30分未満は計算しないということです。

###最終的にやりたいこと
現在、一か月分の実働を計算するという方法を考えていて、、、
前回別の質問で、「項目ごとに集計する」方法をまずは見つけました。
「出勤」=○○時間(実際は秒で計算させます)
「退勤」=○○時間
「休入」=○○時間
「休戻」=○○時間
これなら、【退勤 - 出勤 - (休戻 - 休入) = 結果】という式ができるので、特に問題ありません。
待機も一日に一回であれば、
【退勤 - 出勤 - (休戻 - 休入) - (待戻 - 待入) = 結果】という式だけでなんとかなるかもしれませんが、特殊な例として、(待戻 - 待入)=30分以上か未満かによって、結果が変わること、そして、待機は1日に複数回あるかもしれないことがあるので、一概に上記のように項目ごとに出してしまってはダメになります。

###最後に
上記の一回だけ判定を利用して、「待戻」を入れるときは__直近の「待入」を抽出__して、一度それで計算させて、30分未満ならその待入を削除して待戻はInsertしない。30分ならそのまま待戻をInsertするというやり方はどうかな?と考えました。
基本的にタイムカードなので、常に順番に打刻はされていっているものという前提になるかもしれませんが、、、

もしくは、そもそも打刻をするUser側が時間を見て判断すれば良い話にはなるんですが、、、
30分あると思って入れたら計算したら無かったっていうことはあると思うんです。

なにか、「待機」の部分の判定の仕方として妥当な方法というか、どのような手法をとったら良いかと考えております。
コードなどの話ではないので、大変申し訳ありませんが、、、アドバイスいただければと思います。

###今回の解決策
そもそも情報が不足しており大変申し訳ございませんでした。
テーブル構成としては
id, user, dakoku, timedateとし、闇雲に打刻を打った分だけ入れていくというようなやり方をとってしまっていました。

今回は早速教えていただきました内容として、、、基本的には同様の回答でしたので、テーブル構成から見直していきたいと思っています。

[勤怠]
id, user, 出勤, 退勤, 休入, 休戻

[待機]
id, 待入, 待戻, 計算, 適用

[職員]
id, user

日本語が適切かどうかは置いてくださいw
とりあえずこのような構成にすると、確かに他の悩みも違った解決ができそうですので、やってみたいと思います。

回答いただきましてありがとうございました!
BAをいつも複数答えてくださるとどなたも参考になるので、困るんですが、最初の方にさせていただきます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

テーブル構成がわからないので既にこうなっていたらスルーしてください。
まず基本となる、社員・日付・出勤・退勤・休入・休戻を管理するテーブルが必要です。
待入・待戻は複数回の可能性があるので、別テーブルで管理すればよいと思います。
あとは月別の集計でどうにでもなるかと。
テーブル構成をまとめると以下になります(テーブル名は適当)

勤怠テーブル
社員ID(主キー)
日付(主キー)
出勤
退勤
休入
休戻

待機テーブル
社員ID(主キー)
日付(主キー)
待入(ユニークキー)
待戻

社員マスタ
社員ID(主キー)
社員名

投稿2016/10/14 00:42

ttyp03

総合スコア16998

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Z-TALBO

2016/10/14 00:57

わかりやすい回答ありがとうございます。 実際はテーブル構成としては初心者丸出しのid, user, dakoku, timedateとしていました。 待機テーブルを別にするという発想どころか、勤怠テーブルでは確かに必ず一つは入るだろうという項目だからそういう構造にできますよね。。。 まだまだ勉強不足です。。 大変ありがとうございました!
guest

0

ベストアンサー

待機のテーブルを別テーブルにしたらよいと思われます。
待機時間を記録するテーブルには出退勤テーブルに紐づけられるカラムを用意しておいて、
○○さんのこの日時の待機時間は待機テーブルにいくつ存在するか抽出し、計算していけばよいと思います。

投稿2016/10/14 00:34

s.t.

総合スコア2021

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

s.t.

2016/10/14 00:39

例えばですが、出退勤を記録しているテーブルが id,date,workIn,workOut,restIn,restOut 0001,2016-10-14 9:37:00,2016-10-14 9:37:00,2016-10-14 19:37:00,2016-10-14 12:37:00,2016-10-14 13:37:00 と仮にしておくと、待機テーブルは id,date,waitIn,waitOut,overTime,timeLag 0001,2016-10-14 9:37:00,2016-10-14 9:47:00,2016-10-14 9:57:00,0,00:10:00 0001,2016-10-14 14:37:00,2016-10-14 14:37:00,2016-10-14 15:57:00,1,01:20:00 などという風にしておけば出退勤テーブルとの紐づけができます。
s.t.

2016/10/14 00:43

連投で申し訳ありません。また、私の勘違いであればご容赦ください。 ここから先については、どのくらいの規模で利用するのかなどにもよりますが、 DBとのトランザクションなどやりとりがきにならない程度であればSQLを別にしてプログラム側で計算してやればよいと思います。 1.出退勤テーブルから出退勤時間、休憩時間を引っ張ってくる 2.待機テーブルからその人その日のすべての待機時間を引っ張ってくる 3.計算 もし気になるようであれば、SQLでjoinなどで結合し、1回で引っ張ってくる方法もあります。 このレベルのテーブルではそこまで複雑にはなりませんが、やりたいことが増えてくるとSQLが複雑になりメンテナンスが大変になったりすることもあります。
Z-TALBO

2016/10/14 00:55

何度もコメント投稿していただき、大変ありがとうございます! 実際テーブル構造の考え方でそのように考えてなかったです! もうid,user,dakokuとして、打刻を入れていくというやり方をしてしまっていました。。。 確かに、テーブルの作成の仕方で、他の問題も容易に考えることができそうです! ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問