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の通り。出勤分出力されてしまうんです
文字数制限につき、ソースが載せ切れませんでした。回答頂ければ、そちらに書きたいと思います。

回答の条件
  • URL必須
  • 1人5回まで
  • 登録:
  • 終了:2010/11/22 11:05:02
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答2件)

id:windofjuly No.1

回答回数2625ベストアンサー獲得回数1149

ポイント35pt

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

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

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

f:id:windofjuly:20101115113838j:image

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

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

  

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

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

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

id:goodbabies

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



2010/11/15 12:26:28
id:windofjuly No.2

回答回数2625ベストアンサー獲得回数1149

ポイント35pt

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

  • id:windofjuly
    うぃんど 2010/11/15 15:08:58
    はてなより「返信欄に書き込みがあったことを知らせるメール」が届きました
    ソースコードが書き込まれるのを待っていたのですが書いておられたのですね
    (書き直しをなさった回数分のメールが届いてます)
     
    ※コードは「はてな記法」で囲っておかないと画面上は消される場合があります
    ※消されないまでもHTMLタグによってレイアウトが崩れる場合もあるので「はてな記法」は必須だったりします
    コメント欄では「はてな記法」の必要はありませんが、各行の先頭にある半角スペースが消されてしまってみづらくなる場合もあります
     
    >|php|  ←これが「はてな記法」でphpコードを書く場合に記入するもの(回答欄や返信欄ではこの行自体は表示されません)
    <?php foreach( $all_data as $row ) {?>
    <tr>
    <td><?php echo $row["gid"]; ?></td>
    <td><?php echo $row["name"]; ?><br>
    </td>
    <?php foreach( $dateArray as $d ) {?>
    <td>
    <?php echo $row["work"];?><br/>
    <?php echo $row["syuxtukin"]; ?>
    </td>
    <?php } ?>
    </tr>
    <?php } ?>
    ||<  ←これが「はてな記法」の終了を意味する記号
     
    >|sql|  ←SQLの場合(mysqlやpostgresqlなどの区別はありません)
    SQL文
    ||<
     
    >|vb|  ←VBやVBAの場合
    コード
    ||<
    はてな記法に関して、その他詳細は下記参照
    http://hatenadiary.g.hatena.ne.jp/keyword/%e3%82%bd%e3%83%bc%e3%82%b9%e3%82%b3%e3%83%bc%e3%83%89%e3%82%92%e8%89%b2%e4%bb%98%e3%81%91%e3%81%97%e3%81%a6%e8%a8%98%e8%bf%b0%e3%81%99%e3%82%8b%ef%bc%88%e3%82%b7%e3%83%b3%e3%82%bf%e3%83%83%e3%82%af%e3%82%b9%e3%83%bb%e3%83%8f%e3%82%a4%e3%83%a9%e3%82%a4%e3%83%88%ef%bc%89
  • id:goodbabies
    何度もメールが届いてしまったのですね。失礼しました。はてな記法は全く知りませんでした・・・(涙)

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません