アプリ版:「スタンプのみでお礼する」機能のリリースについて

これから1ヶ月の間に誕生日を迎える社員を抽出して表示する

データベースを作成してここ1ヶ月に誕生日を迎える社員を表示したいです。

12月05日 木村
12月21日 佐々木
01月02日 加藤

上記のように表示したいです。日付が12月6日になったら12月5日生まれの木村は消える。

テーブル名 shop
name VARCHAR型
birth DATE型

name | birth
-----------------
田中|1992-11-15
吉田|1990-10-01
佐藤|1885-08-02

検索してみて似たようなものを真似してみたのですが、何も表示されない状態です。

--------------------------------------------------------------------

$stmt = $dbh -> query("SELECT * FROM shop WHERE birth BETWEEN curdate() - interval 1 month + interval 1 day AND curdate()");
while($row = $stmt -> fetch()){
print date('m月d日',strtotime($row['birth']));
print($row['name']);
}

--------------------------------------------------------------------

これはどのようにしたら抽出して表示できるでしょうか?

ご存知の方いらっしゃいましたらご教示ください。
よろしくお願いします。

A 回答 (4件)

相互リンク


http://detail.chiebukuro.yahoo.co.jp/qa/question …

同じことしか書きませんww

以下、質問者さんにならって私もコピペ

-------------------------------------------------------

少なくとも年月日で保持しているbirthをそのまま使うのは無理だと思いますね。date_formatで月日だけ切り出すべきでしょ

$stmd = date('m/d');
$endmd = date('m/d', strtotime('+1month'));
if ($stmd < $endmd) {
$sql = "SELECT * FROM shop where date_format(birth, '%m/%d') >= '$stmd' and date_format(birth, '%m/%d') <= '$endmd'";
} else {
$sql = "SELECT * FROM shop where date_format(birth, '%m/%d') >= '$stmd' or date_format(birth, '%m/%d') <= '$endmd'";
}




少なくとも、こちらで(テストデータを登録して)試した限りでは上記ソースで問題なく抽出されますので・・・

以下がテストに使ったソース全文です。最終的には同じSQLが生成されるハズです(上記のソースで生成したSQL文をphpMyAdminでSQL実行した結果も確認しています)。

<?php
$pdo = new PDO("mysql:host=localhost;dbname=test;charset=utf8", "root", "");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$stmd = date('m/d');
$endmd = date('m/d', strtotime('+1month'));
$join = $stmd < $endmd ? 'and' : 'or';
$sql = "SELECT * FROM shop where date_format(birth, '%m/%d') >= ? " . $join . " date_format(birth, '%m/%d') <= ?";
try {
$sth = $pdo->prepare($sql);
$sth->execute(array($stmd, $endmd));
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
print "<pre>";
var_dump($row);
print "</pre><hr />";
}
} catch (PDOException $e) { die($e->getMessage()); }
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
こちらの方が何度もやり取りできるので良いですね。

実行してみた結果、下記のように配列のコードがずらっと表示されます。
1ヶ月以内に誕生日を迎える社員だけ配列に格納できているんですが、ここからどうやって「月日」と「名前」を並べられるかが分かりません。

array(19) {
["フィールド名"]=>
string(2) "値"



}
array(19){
["フィールド名"]=>
string(2) "値"
}




よろしくお願いします。

お礼日時:2013/12/03 18:25

>1ヶ月以内に誕生日を迎える社員だけ配列に格納できているんですが、


>ここからどうやって「月日」と「名前」を並べられるかが分かりません。

$row['birth']と$row['name']に生年月日と名前が取得できているんですから、それを表示するだけです。

ご自分が最初に書かれたソースにはその部分が含まれていますよ(理解しないでコピペだけしたのでしょうか)。さすがにそこから説明するのは・・・とも思いますし、どういう表示にしたいかは好みの問題です。

while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
print date('m月d日', strtotime($row['birth'])) . '' . $row['name'] . '<br />' . PHP_EOL;
}

この回答への補足

ORDER BY date_format(birth, '%m/%d')でソートはできました。
しかし現時点では下記のように1月が頭にきてしまいます。
これを防ぐ方法はないでしょうか?

01月02日 佐々木
12月05日 伊藤
12月15日 佐伯

よろしくお願いします。

補足日時:2013/12/03 21:56
    • good
    • 0
この回答へのお礼

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

ご教示頂いた方法で表示されたのですが、日付がテレコになってしまいます。
SQL文の最後に「ORDER BY birth」を追加してみましたが何も変わらず。
どのようにすれば日付順に並べることができるでしょうか?

何度も申し訳ないですが、よろしくお願いします。

お礼日時:2013/12/03 19:37

>ご教示頂いた方法で表示されたのですが、日付がテレコになってしまいます。


>SQL文の最後に「ORDER BY birth」を追加してみましたが何も変わらず。
>どのようにすれば日付順に並べることができるでしょうか?

質問者さんが考えている『日付順』とはどういう並びなんでしょうか?「ORDER BY birth」なら生年月日順になっているハズです。

>ORDER BY date_format(birth, '%m/%d')でソートはできました。
>しかし現時点では下記のように1月が頭にきてしまいます。
>これを防ぐ方法はないでしょうか?

「防ぐ」とは?そう並ぶようにSQL文をかいているのですから、それを防ぐことは出来ませんよ。


取り出してから(php側で配列に格納するなどしてから)好きな順に並び替えて表示してもいい話ではないですかね(そもそも、現状ではphpは無関係でSQLの書き方の話になってます)。


#そもそも最初の質問では order に関しては何も書かれていません。後出しされても困ります。
#こちらも相手がクライアントなら気をつけますが、少なくとも質問者さんは「作る側」ですよね。


もしどうしてもデータベースからの取り出し時に「誕生日が近い順」に取り出したいのであれば

$stmd = date('m/d');
$endmd = date('m/d', strtotime('+1month'));
$join = $stmd < $endmd ? 'and' : 'or';
$sql = "SELECT shop.*, (case date_format(birth, '%m/%d') <= ? then 1 else 0 end) as sw FROM shop where date_format(birth, '%m/%d') >= ? " . $join . " date_format(birth, '%m/%d') <= ? order by sw, date_format(birth, '%m/%d')";
try {
$sth = $pdo->prepare($sql);
$sth->execute(array($stmd, $stmd, $endmd));
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
print date('m月d日', strtotime($row['birth'])) . '' . $row['name'] . '<br />' . PHP_EOL;
}
} catch (PDOException $e) { die($e->getMessage()); }

でいいと思います。

swの値が誕生日が当年なら0, 翌年なら1 になるのはわかりますよね(月日が現在の月日以前で抽出対象になるのは「翌年」のものなので)。$joinを"and"と"or"で使い分けているのが理解出来ていれば自明だとは思いますが・・・

この回答への補足

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

実行してみましたが、エラー文がでるだけです。
エラー文は下記のようになっています。

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'then 1 else 0 end) as sw FROM shop where date_format(birth, '%m/%d') >= '12/04' at line 1

補足日時:2013/12/04 21:51
    • good
    • 0

失礼。

whenを書き漏らしてましたね。

$pdo = new PDO("mysql:host=localhost;dbname=test;charset=utf8", "root@localhost", "");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$stmd = date('m/d');
$endmd = date('m/d', strtotime('+1month'));
$join = $stmd < $endmd ? 'and' : 'or';
$sql = "SELECT shop.*, (case when date_format(birth, '%m/%d') <= ? then 1 else 0 end) as sw FROM shop where date_format(birth, '%m/%d') >= ? " . $join . " date_format(birth, '%m/%d') <= ? order by sw, date_format(birth, '%m/%d')";
try {
$sth = $pdo->prepare($sql);
$sth->execute(array($stmd, $stmd, $endmd));
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
print date('m月d日', strtotime($row['birth'])) . '' . $row['name'] . '<br />' . PHP_EOL;
}
} catch (PDOException $e) { die($e->getMessage()); }

(前回との違いは$sqlへ代入する文字列リテラルだけです)
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
先ほど実行してみたら出来ました。
助かりました。ありがとうございます。

お礼日時:2013/12/06 15:38

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!