SQLおよびPHPに関する質問です。

予約管理に関するDBテーブル(yoyaku)が(id person email time date)の5つのフィールドで構成されているとします。
ある日付(date)に予約してある人(person)に予約時間(time)をメール(email)で送信するプログラムを書こうとしています。
以下のようなプログラムでメール送信はできるのですが、これだと同じ人が複数の時間に予約しある場合、その数だけメールが届いてしまいます。

1人で同じ日に複数の時間に予約してある場合は全ての時間をまとめてメールで送信したいのです。
どうしたらいいのでしょう。何かアドバイスお願いします。

$sql = "SELECT * FROM yoyaku WHERE date = 'ある日付'";
$rst = mysql_query($sql, $con);
while($col = mysql_fetch_array($rst)){
メール送信プログラム
}

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2009/10/06 15:12:21
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:ycyc No.2

回答回数37ベストアンサー獲得回数6

ポイント28pt

同じ人の場合、配列にデータをためておき、まとめて送信すればいいのではないでしょうか?

$sql = "SELECT * FROM yoyaku WHERE date = 'ある日付' order by person,time";

$rst = mysql_query($sql, $con);

$person = "";

// 配列の初期化

$list = array();

while($col = mysql_fetch_array($rst)){

 if ( $person = $col["person"] ) {

  // 同じ人なら配列に保存

  $list[] = $col;

 } else {

  // 違う人なら $list の内容を※メール送信プログラム

  // 配列の初期化

  $list = array();

  // 配列に保存

  $list[] = $col;

  $person = $col["person"]

 }

}

// 最後の人用の※メール送信プログラム


※メール送信プログラムでは、

 if ( count($list) > 0 ) {

  // メール送信

 }

id:shinwa-tokyo

ありがとうございます。

わかりやすくコードまで書いて頂き感謝いたします。

SQLでGROUP BYなどとしてあるフィールドだけ配列で返すような

やりかたはやっぱりないんでしょうかね。

(mysql_fetch_arrayの場合は結果的に2次元配列になるような…)

とりあえず教えて頂いた方法で進めてみます。

2009/10/06 15:08:37

その他の回答2件)

id:chuken_kenkou No.1

回答回数722ベストアンサー獲得回数54

ポイント26pt

全ての時間をまとめてメールで送信したい

「まとめて1通で」でしょうか?

SELECT文に「ORDER BY person」を追加。

SELECT * FROM yoyaku WHERE date = 'ある日付'
 ORDER BY person

mysql_fetch_arrayで得られるpersonの値を変数で保存しておき、personの値が変わったときに直前のpersonへのメール送信を行うようにすればいいのではないでしょうか?

id:shinwa-tokyo

ご回答ありがとうございます。

やっぱりPHPで解決するしかないみたいですね。

質問の仕方が悪かったのかもしれませんが、

SQLでGROUP BY PERSONなどとしてあるフィールドの値を

配列でそのまま受け取れる方法なんかはないんだろうかと考えていました。

教えていただた方法でとりあえず進めます。

2009/10/06 15:08:32
id:ycyc No.2

回答回数37ベストアンサー獲得回数6ここでベストアンサー

ポイント28pt

同じ人の場合、配列にデータをためておき、まとめて送信すればいいのではないでしょうか?

$sql = "SELECT * FROM yoyaku WHERE date = 'ある日付' order by person,time";

$rst = mysql_query($sql, $con);

$person = "";

// 配列の初期化

$list = array();

while($col = mysql_fetch_array($rst)){

 if ( $person = $col["person"] ) {

  // 同じ人なら配列に保存

  $list[] = $col;

 } else {

  // 違う人なら $list の内容を※メール送信プログラム

  // 配列の初期化

  $list = array();

  // 配列に保存

  $list[] = $col;

  $person = $col["person"]

 }

}

// 最後の人用の※メール送信プログラム


※メール送信プログラムでは、

 if ( count($list) > 0 ) {

  // メール送信

 }

id:shinwa-tokyo

ありがとうございます。

わかりやすくコードまで書いて頂き感謝いたします。

SQLでGROUP BYなどとしてあるフィールドだけ配列で返すような

やりかたはやっぱりないんでしょうかね。

(mysql_fetch_arrayの場合は結果的に2次元配列になるような…)

とりあえず教えて頂いた方法で進めてみます。

2009/10/06 15:08:37
id:Mook No.3

回答回数1314ベストアンサー獲得回数393

ポイント26pt

テーブルの項目名として予約後に引っ掛かりそうな time などは使用しない方がよさそうに思いますが、

それはさておき下記のように処理してはどうでしょうか。


メール送信を id 単位で送るようにいったん変数に格納し、id が変化したタイミングで送るようにしています。

クエリの数が増えますが、id でループを回し、その中で id 単位でクエリをかけても実現できるかと思います。

<?php

function メール送信プログラム( $person, $email, $timeArray ) {
    $body = "本日の予約時間は次の通りです。\n";
    for ( $ i = 0; $i < count( $timeArray ); $i++ ) {
        $body .= $timeArray[$i]."\n";
    }
    // 送信処理・・・
}

// クエリ結果を id, time ORDER で取得
$sql = "SELECT * FROM yoyaku WHERE date = 'ある日付' ORDER BY id, time";
$rst = mysql_query($sql, $con);
$id="";
$timeArray = Array();
while($col = mysql_fetch_array($rst)){
    timeArray[] =  $col['time'];
    if( $id != $col['id'] )
        if( $id != "" ) {
            メール送信プログラム( $person, $email, $timeArray );
	        array_splice( $timeArray,0);
        }
        $id = $col['id'];
        $person = $col['person'];
        $email =  $col['email'];
    }
}

if( count( $timeArray ) > 0 ) {
    メール送信プログラム( $person, $email, $timeArray );
}


?>
id:shinwa-tokyo

ご回答ありがとうございます。

例にだした項目名は簡易的に書かせて頂いたので、

本当のDBではプリフィックスなどがついています。

私の説明不足が原因なのですが、

idは予約にあたえられたものです。

でも基本的にtimeを配列に格納する方法で

なんとかなりそうです。

2009/10/06 15:11:57
  • id:chuken_kenkou
    >SQLでGROUP BYなどとしてあるフィールドだけ配列で返すような
    >やりかたはやっぱりないんでしょうかね。

    MySQL限定なら、独自機能で「GROUP_CONCAT」関数というものがあります。

    http://dev.mysql.com/doc/refman/4.1/ja/group-by-functions.html

  • id:shinwa-tokyo
    ありがとうございます!
    まさに探していたのはこれです。
    試してみたところこれで思っていた通りの結果が得られました。

    $sql = "SELECT person, email, GROUP_CONCAT(time ORDER BY time ASC SEPERATOR ',') AS timelist FROM yoyaku WHERE date = 'ある日付' GROUP BY person";

    ささやかですがお礼にポイントを送らせて頂きます。

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

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

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

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