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

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

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

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

PHP

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

Q&A

解決済

4回答

6036閲覧

foreach 配列 合計を出したい

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/13 08:28

編集2016/10/13 09:27

説明が苦手なのですが、、、
やりたいこととしては、時刻の計算にはなるのですが、DBにある値を引っ張ってきてからっていう話です。

###DBの設計

MySQL

1id int not null auto_increment 2user int 3dakoku int 4dakoku_time datetime

単純に上記のような設計とします

###中に入っているデータ
○○さん 出勤 2016/10/12 09:00:00
○○さん 退勤 2016/10/12 18:00:00
○○さん 出勤 2016/10/13 09:00:00
○○さん 退勤 2016/10/13 18:00:00
上記のようなデータがデモで入っているとします。

###foreachなどを使った取得
基本的にforeachなどを使用して「取得することや表示」はできるのですが、、、
そのforeachの中でやりたいこととしては
1.時刻の部分だけを抜き取る(年月日はいらない)
->substrなどを使ったらできました
2.時刻を計算するので、秒に直してみる
->1で抜き取ってそれを秒に直すだけなのでできました
3.取得したデータをようはSUM関数の要領で合計を出したい
->この部分がイマイチよくわからず、、、できていません

###やってみたこと

PHP

1// 出勤の部分だけを抽出とします 2$in_time = in_time_db(); // DBからデータを抽出して代入 3foreach($in_time as $in){ 4 $in_date = $in['dakoku_time']; // 日時が抽出されました 5 $substr_in = substr($in_date, 11, 18); // 時刻だけになりました09:00:00 6 $sec_in = h2s($in_date); // function使ってますが、とりあえず32400にはなりました 7 // 試しに 8 $sum_in = array_sum($sec_in); // エラーでダメでした、配列になってないから? 9}

ということで、上記のとこで詰まりました。
配列じゃなくなってしまっている?感じがしたので、それがarray_sum()にならない原因かと思ったのですが、$sec_inという物だけを配列にしていく方法が浮かばず、、、

###最終的にやりたいこと
最終的には「一か月分の○○さんの働いた時間を出す」なんですが、
上記のように考えたのは、出勤の合計秒と退勤の合計秒を出せばあとはそれを引けばいいんじゃない?とか思ったからです。

###最後に
当然、考え方などアプローチ方法はいくらでもあるでしょうが、とりあえず私のレベルだとこういう感じで考えました。
他にも良いアドバイスなどいただければと思っております。

説明が下手で不足している情報があるかと思いますので、ご指摘ください。
よろしくお願いします。

###今回の解決策

PHP

1// 出勤の部分だけを抽出とします 2$in_time = in_time_db(); // DBからデータを抽出して代入 3foreach($in_time as $in){ 4 $in_date = $in['dakoku_time']; // 日時が抽出されました 5 $substr_in = substr($in_date, 11, 18); // 時刻だけになりました09:00:00 6 $sec_in = h2s($in_date); // function使ってますが、とりあえず32400にはなりました 7 $sum_in = bcadd($sum_in, $sec_in); 8} 9return $sum_in;

bcadd()というのを初めて知りました、、、
これにより、最終的に計算された値を返すことができました!

###もう一つの解決策

PHP

1// 出勤の部分だけを抽出とします 2$sec_in_array = array(); // 配列用の初期化 していないとエラー 3$in_time = in_time_db(); // DBからデータを抽出して代入 4foreach($in_time as $in){ 5 $in_date = $in['dakoku_time']; // 日時が抽出されました 6 $substr_in = substr($in_date, 11, 18); // 時刻だけになりました09:00:00 7 $sec_in = h2s($in_date); // function使ってますが、とりあえず32400にはなりました 8 // やはり配列じゃなくなっているのが原因なので、配列に戻す 9 array_push($sec_in_array, $sec_in); 10} 11// ループから出てから計算 12$sum_in = array_sum($sec_in_array); 13return $sum_in;

ということで、今回はいろいろ勉強になりました。
ループ内で計算して出してくるのか?
ループ外で計算するのか?
どちらも知ることができて大変感謝です。

今回は、上記二つの方法でどちらが自分に合ってるかなどを考えつつ、やってみたいと思います。

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

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

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

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

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

guest

回答4

0

お気づきの通り、配列になっていないからですよ~
要は、foreachの処理は秒に変換し配列に戻す処理と考えた方が良いかと思います。
foreachの処理後にarray_sum()で合計を出されてはいかがでしょうか。
array_sum()を使用する場合は、多分これでいけるはず!(試してません)

$sec_in_array = array(); $in_time = in_time_db(); // DBからデータを抽出して代入 foreach($in_time as $in){ $in_date = $in['dakoku_time']; // 日時が抽出されました $substr_in = substr($in_date, 11, 18); // 時刻だけになりました09:00:00 $sec_in = h2s($in_date); // function使ってますが、とりあえず32400にはなりました array_push($sec_in_array, $sec_in); } $sum_in = array_sum($sec_in_array);

あっ!ベストアンサーが選ばれている..遅かったか。汗

投稿2016/10/13 09:05

編集2016/10/13 09:07
Yousuck

総合スコア349

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

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

Z-TALBO

2016/10/13 09:23

回答ありがとうございます! 配列の戻し方に関して教えていただきありがとうございます! array_push()自体は見たことあるんですが、ここでの使い方とかもイマイチな理解度でした。 とりあえず、こちらの方法も試してみたところきちんと思ったとおりの結果を出力できました! 今回は早い順でBAをつけてしまったところはありますが、回答いただき本当にありがとうございます!
guest

0

php上のループで合計を出さずに、
mysqlへのクエリーで合計を出した方が速そうな気がします。
mysqlでは日付時刻に関する演算子や関数も豊富そうだし。

投稿2016/10/13 09:02

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Z-TALBO

2016/10/13 09:18

回答ありがとうございます! 確かに、DB上でとりあえずできるかなと思ったのですが、、、なんとなくPHPでいじったほうが性にも合いそうでw そういう方法も探しつつやってみたいと思います。
guest

0

ベストアンサー

bcadd()を使って加算する方法もあります。

// 出勤の部分だけを抽出とします $in_time = in_time_db(); // DBからデータを抽出して代入 foreach($in_time as $in){ (略) $sum_in = bcadd($sum_in ,$sec_in); //加算処理 }

投稿2016/10/13 08:37

nobinobi

総合スコア199

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

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

Z-TALBO

2016/10/13 08:59

回答ありがとうございます! やってみた結果なんとか欲しい値が取得できました。 少しこれでいじってみようと思います!
guest

0

ご参考にSQLで作成してみました(遅いけど)

sql

1/**** 2テーブル情報の前提と選択値を以下の様にしました。 3dakoku 出勤:0 退勤:1 4user=100 月=201610 5*****/ 6 7SELECT t3.user, DATE_FORMAT(t3.dakoku_time, '%Y%m') mm, SEC_TO_TIME(SUM(sec)) amt 8 FROM 9 (SELECT t1.user, t1.dakoku_time, TIME_TO_SEC(TIMEDIFF(t2.dakoku_time, t1.dakoku_time)) sec 10 FROM 11 (SELECT @i:=@i+1 as num, user, dakoku_time from (select @i:=0) as dummy,timerec 12 WHERE user=100 AND dakoku=0 AND DATE_FORMAT(dakoku_time, '%Y%m')='201610') t1 13 JOIN 14 (SELECT @j:=@j+1 as num, user, dakoku_time from (select @j:=0) as dummy,timerec 15 WHERE user=100 AND dakoku=1 AND DATE_FORMAT(dakoku_time, '%Y%m')>='201610') t2 16 USING (num) 17) t3 GROUP BY 1,2 18;

投稿2016/10/13 10:15

A.Ichi

総合スコア4070

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

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

Z-TALBO

2016/10/13 23:43

SQLでの回答大変ありがとうございます! こういう書き方があるんですね、、、 とても参考になります!ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問