POSTGRESQLのSQLで以下はどのように書くのでしょうか?


PHPでかきます。
PHPでの変数を年を$year、月を$monthとします。

テーブルAは次のようになっています。(ins_dateはdate型)
no price ins_date
1 5000 2006-03-01
2 4000 2005-10-10
3 3000 2006-01-11
4 2000 2006-02-15
5 1000 2005-12-24
6 2000 2006-02-24

ここから、
(1)$year年$month月を含んで、それよりも前の期間のselect結果
(例えば2005年12月だとしたら、2005年12月までの結果。noで言うと、2と5が結果としてでるようなSQL)

(2)$year年$month月の結果
(例えば2006年02月だとしたら、2006年02月までの結果。noで言うと、4と6が結果としてでるようなSQL)

自分では以下のようになるかと思ったのですが、どうも結果が違うようです。
(1)"select * from table_A where ins_date < '".$year."-".$month."-01' + '1months'"

(2)"select * from table_A where ins_date between '".$year."-".$month."-01' and '".$year."-".$month."-01' + '1months'"

'1months'あたりが違うような気がしているのですが、このようなときどのように書くのでしょうか?

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2006/03/22 17:30:07
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答3件)

id:kimizu No.1

回答回数726ベストアンサー獲得回数21

ポイント27pt

日付と比較するときに、文字列で比較するのはNG。

比較でやるなら比較対象文字列を日付型に変換しないとダメだと思うデス。

1) $year年$month月を含んで、それよりも前の期間のselect結果

select * from table_A where ins_date <= (to_date('$year$month01','YYMMDD')+'1 months'+'-1 days');

2) $year年$month月の結果

select * from table_A where to_char(ins_date,'yyyy.mm.dd') like '$year$month%';

出来たselect文を試しに画面出力してみると解りやすいかも。

結果が違う、とは具体的にどのように出力されてしまうのかを

書いた方が回答しやすいと思いますよ。

id:iiiiiiiii

ありがとうございます。

試してみます。

2006/03/22 17:29:26
id:birdie-brain No.2

回答回数40ベストアンサー獲得回数4

ポイント27pt

年+月で条件を指定するのが目的であれば、もっと単純な方法があります。

date_trunc()関数を使って、ins_dateの日付を年+月に切り詰めてしまえばよいのです。

たとえば、質問(1)と(2)は以下の通りに記述できます。

(1) "SELECT * FROM table_A WHERE date_trunc('month', ins_date) <= to_date('".$year."-".$month."-01"', 'YYYY-MM-DD')"

(2) "SELECT * FROM table_A WHERE date_trunc('month', ins_date) = to_date('".$year."-".$month."-01"', 'YYYY-MM-DD')"

id:iiiiiiiii

ありがとうございます。

うまくいきました。

2006/03/22 17:29:31
id:bonlife No.3

回答回数421ベストアンサー獲得回数75

ポイント27pt

(1)

select * from table_A where ins_date < to_date('$year-$month','YYYY-MM') + interval '1 month';

ins_dateがdate型なのであれば、$year、$monthをto_date関数で明示的にdate型に変換した後、比較した方が良いと思います。

http://www.postgresql.jp/document/pg813doc/html/functions-fo...

to_dateについては上記のURLの内容をご確認ください。

to_date関数でYYYYMMまでの指定をすると、dateは自動的に01日00時00分00秒になります。

日付の計算はPostgreSQLでは間隔(interval)を足す、あるいは引く、といったイメージになりますので、今回のケースでは、intervalを+する必要があります。

これで、ins_dateが$year、$monthで指定した値の翌月の01日00時00分00秒より前のものを選択することが出来るはずです。

http://www.postgresql.jp/document/pg813doc/html/functions-da...

プラス演算子(+)の使い方については上記のURLの内容をご確認ください。

('1 month'の部分は'1 months'でも良かったはずです。)

(2)

確かPostgreSQLにはbetween関数はなかったと思います。(記憶違いでしたらすみません。)

単純に

  • $year、$monthで指定した月の01日00時00分00秒以降
  • $year、$monthで指定した月の翌月の01日00時00分00秒より前

という条件をwhere句で指定すれば良いはずです。

select * from table_A where ins_date >= to_date('$year-$month','YYYY-MM') and ins_date < to_date('$year-$month','YYYY-MM') + interval '1 month';

現在、PostgreSQLを試せる環境がないので、チェックはできておりません。

一度試してみてください。

id:iiiiiiiii

ありがとうございます。

こちらもうまくいきました。

2006/03/22 17:29:43
  • id:bonlife
    あらためて見るとid:birdie-brainさんのやり方がキレイですね。
    精度を月レベルまで落として(言い換えると01日00時00分00秒に合わせてしまって)比較するのが本来の目的にも沿っていて良いと思います。
    勉強になりました。
    ただ、
    to_date('".$year."-".$month."-01"', 'YYYY-MM-DD')
    の部分は01という日を指定する必要はないので、
    to_date('$year-$month', 'YYYY-MM')
    とした方がSQLが短くなって良い気がしました。

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

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

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

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