人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

PHP+Mysqlで出勤管理のプログラムを作っています。出勤の登録は問題なく作れたものの、出力で手間取っています。
employeeテーブル ・・・社員登録用
CREATE TABLE `employee` (`gid` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(50) NOT NULL,UNIQUE KEY `gid` (`gid`))
workテーブル ・・・シフト登録用テーブル
CREATE TABLE `work` (`time_id` int(11) NOT NULL AUTO_INCREMENT,`gid` int(11) DEFAULT NULL,`work` enum('true','false') DEFAULT 'false',`day` date DEFAULT '0000-00-00',`syuxtukin` time DEFAULT NULL,`taisya` time DEFAULT NULL,PRIMARY KEY (`time_id`))
この2つがあります。一週間分のスケジュールを出力したいのですが、
SELECT employee.gid,employee.name,employee.uid,work.work,work.syuxtukin,work.taisya,work.day FROM employee LEFT JOIN (SELECT gid,syuxtukin,taisya,work,day FROM work WHERE day >= '2010-11-01' AND day <='2010-11-07') work ON employee.gid = work.gid ORDER BY employee.gid DESC;
これで全社員の一週間分の出勤データを引っ張ることができたのですが、出力がうまくいきません。

http://www.m-musicom.com/test.html
出力結果はURLの通り。出勤分出力されてしまうんです
文字数制限につき、ソースが載せ切れませんでした。回答頂ければ、そちらに書きたいと思います。

●質問者: goodbabies
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:00 2010-11-01 2010-11-07 enum GID
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● うぃんど
●35ポイント

【1】人力検索の使い方の例

すでにご存知のものもあるかもしれませんが他の人の役に立つかもしれないので書いておきます

(例1)文字数制限に関しては「回答受付中もコメント・トラックバックを表示」にチェックを入れてコメント欄を利用可能な状態にして、コメント欄に続きを書き込むという手が使えます

f:id:windofjuly:20101115113838j:image

http://f.hatena.ne.jp/windofjuly/20101115113838

(例2)はてなダイアリーという無料のブログがありますので、ダイアリーを開設し、質問本文をダイアリーに投稿し、そのアドレスを人力検索の質問文に書くという手も使えますが上記に比べれば準備が必要なので面倒ですね

【2】とりあえず質問文から推測しての回答

出勤管理一覧の形にクロス集計を行う際に GROUP BY gid を入れていないだけだと思われます

(リンクを辿ると、あなたがどのような仕事をしているのかが丸見えになりますし、はてな外部にて関連情報を用意しなければならない場合を除いては質問との関連性の保持を考慮すべきだとも思いますので、出来る限りで結構ですが表などは画像としてローカルに保存した後に「はてなフォトライフ」にアップしたり「はてなダイアリー」にアップしたりするのが良いでしょう)

◎質問者からの返答

いつもありがとうございます。またさらにお気遣い頂きありがとうございます。名前は重複しなかったものの、出勤時間まで出力してみると、1行全て(15日?21日まで)同じ値が入ってしまいました。どうすればよいのでしょう・・




2 ● うぃんど
●35ポイント

GROUP BY はSQLだけでやろうとしただけの思いつきなので、ご勘弁ください

【改造例】

(1)日付順に並んでいるという保証はどこにもありませんので、とりあえず追加しておきましょう

BETWEENの部分を括弧で囲む必要はありませんが判読性アップのために入れてあります

BETWEENではなく質問文のままにしてももちろんかまいませんが、まだご存知ない構文でしたら記述が楽になりミスも防げるので覚えておくと良いと思います

SELECT em.gid, em.name, em.uid, wk.work, wk.syuxtukin, wk.taisya, wk.day
FROM employee em
 LEFT JOIN (
 SELECT gid,syuxtukin,taisya,work,day
 FROM work
 WHERE (day BETWEEN '2010-11-01' AND '2010-11-07')
 ) wk ON employee.gid = work.gid
ORDER BY em.gid DESC, wk.day;

(2)php側では1レコードずつ出力する際に社員が変わったら改行するような処理にしましょう

<?php
 echo "<table>\n";
 echo "<tr>\n";
 echo '<th>社員ID</th><th>名前</th><th>' . join('</th><th>', $dateArray) . "</th>\n";
 $pre = '';
 foreach( $all_data as $row ) {
 if ( $row["gid"] <> $pre ) {
 $pre = $row["gid"];
 echo "</tr>\n<tr>\n";
 echo '<td>' . $row["gid"] . "</td>\n";
 echo '<td>' . $row["name"] . "</td>\n";
 }
 echo '<td>' . $row["work"] . "</td>\n";
 echo '<td>' . $row["syuxtukin"] . "</td>\n";
 }
 echo "</tr>\n";
 echo "</table>\n";
?>

【まだ残っている問題点】

・社員Aは一週間分のデータが存在するけれど社員Bには'2010-11-01'、'2010-11-02'、'2010-11-07'の3日分しかデータが無いなどの場合は上記では想定外です

(workテーブルに社員Bのデータが3日分しかなかった場合は表がずれますので、やってみると良いでしょう)

・3日分しかなかった場合などに対応する方法は1つではありません。 SQLの結果を$all_dataに読み込む際に横並びのデータに替えてしまうのが楽かもしれません

(その部分のコードがあれば、夜にでも改造しましょう)

http://dev.mysql.com/doc/refman/5.1/ja/comparison-operators.html

http://php.net/manual/ja/function.join.php

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ