• ベストアンサー

SQL文を教えてください。

特定の日付Xを指定した場合、 以下のような結果になるSQL文を教えてください。 よろしくお願いします。 1) 日付X = 2003-12-17 の場合 ID table_A_DATE table_B_DATE table_C_DATE ------------------------------------------------ 001 2003-12-10 2003-12-12 2003-12-14 002 2003-12-15 ---------- 2003-12-16 003 2003-12-06 2003-12-10 ---------- 004 2003-12-08 ---------- ---------- 2) 日付X = 2003-12-11 の場合 ID table_A_DATE table_B_DATE table_C_DATE ------------------------------------------------ 003 2003-12-06 2003-12-10 ---------- 004 2003-12-08 ---------- ---------- table A(テーブルAには全ユーザのデータがあります) ID DATE ------------------ 001 2003-12-10 002 2003-12-15 003 2003-12-06 004 2003-12-08 table B ID DATE ------------------ 001 2003-12-12 003 2003-12-10 table C ID DATE ------------------ 001 2003-12-14 002 2003-12-16

質問者が選んだベストアンサー

  • ベストアンサー
  • BellBell
  • ベストアンサー率54% (327/598)
回答No.5

結果を見ると、結合の方は成功しているので、WHERE選択条件が間違っていますね。 ということは、#1で書いた 3)BがNULLであるか、日付がX以前であるようにWhereを記述 4)CがNULLであるか、日付がX以前であるようにWhereを記述 でやっぱりNULLであるかの判定をしなきゃいけないようです。(SQLしばらくさわっていないため錆付いています) WHERE (table_A.DATE <= 日付X) AND ((table_B.DATE IS NULL) OR (table_B.DATE <= 日付X )) AND ((table_C.DATE IS NULL) OR (table_C.DATE <= 日付X )) では多分OKでしょう。 PostgreSQLの仕様はわかりませんが、 table_B(C).DATE IS NULL の部分が table_B(C).DATE = NULL になるかも知れません。

BottleCap
質問者

お礼

おかげさまで、思い通りの結果が出ました。 ありがとうございました。

その他の回答 (6)

  • yomo3
  • ベストアンサー率32% (88/269)
回答No.7

#6ざんす。 日付の指定を3つともしなければならないのならば、 WHERE ((table_A.DATE<=日付X) AND (table_B.DATE<=日付X Or table_B.DATE Is Null) AND (table_C.DATE<=[日付X] Or table_C.DATE Is Null); みたいに、Nullも加えないと、拾ってくれないように思います。

  • yomo3
  • ベストアンサー率32% (88/269)
回答No.6

これじゃあ、だめかなぁ…… SELECT table_A.ID, table_A.DATE AS table_A_DATE, table_B.DATE AS table_B_DATE, table_C.DATE AS table_C_DATE FROM (table_A LEFT JOIN table_B ON table_A.ID = table_B.ID) LEFT JOIN table_C ON table_A.ID = table_C.ID WHERE ((table_A.DATE)<=日付X);

  • BellBell
  • ベストアンサー率54% (327/598)
回答No.4

FROM内のLEFT JOIN結合に、ON結合条件式を見事に書き落としていました。またまた、ボケてました。 結合できるわけありません、失礼しました。 1) FROM [table_A] LEFT JOIN ([table_B] LEFT JOIN [table_C] ON table_B.ID = table_C.ID) ON table_A.ID = table_B.ID 2) FROM ([table_A] LEFT JOIN [table_B] ON table_A.ID = table_B.ID) LEFT JOIN [table_C] ON table_A.ID = table_C.ID 1)は下のFROMに結合条件を入れたものです。 A+(B+C) 2)の書き方の方が、結合式と結合条件式が隣接するためわかりやすいかな、と思い書き直しました。 (A+B)+C 全文を書くとこうなります SELECT table_A.ID, table_A.Date table_A_DATE, table_B.Date table_B_DATE, table_C.Date table_C_DATE FROM ([table_A] LEFT JOIN [table_B] ON table_A.ID = table_B.ID) LEFT JOIN [table_C] ON table_A.ID = table_C.ID WHERE (table_A.DATE <= 日付X) AND (table_B.DATE <= 日付X ) AND (table_C.DATE <= 日付X )

BottleCap
質問者

補足

何度もありがとうございます。 実行してみましたが 残念ながら結果は以下のようになりダメでした。 1) 日付X = 2003-12-17 の場合 ID table_A_DATE table_B_DATE table_C_DATE ------------------------------------------------ 001 2003-12-10 2003-12-12 2003-12-14 2) 日付X = 2003-12-11 の場合 ID table_A_DATE table_B_DATE table_C_DATE ------------------------------------------------ なし

  • BellBell
  • ベストアンサー率54% (327/598)
回答No.3

#1です PostgreSQLは使用したことがないですが、下記リンクのページを参考に書くとこうなります。 SELECT table_A.ID, table_A.Date table_A_DATE, table_B.Date table_B_DATE, table_C.Date table_C_DATE FROM [table_A] LEFT JOIN ([table_B] LEFT JOIN [table_C]) WHERE (table_A.DATE <= 日付X) AND (table_B.DATE <= 日付X ) AND (table_C.DATE <= 日付X ) 下では、『B(C)がNULLであるか、』などとボケたことを書いていますね、その部分忘れてください。

参考URL:
http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/psql_k08.htm
BottleCap
質問者

補足

上のSQLでうまく動かなかったので 下のようになおして動かしてみました。 ですが、思うような結果は得られませんでした。 考えれば考えるほど なんか実現できないような気がしてきました・・。 SELECT table_A.ID, table_A.Date as table_A_DATE, table_B.Date as table_B_DATE, table_C.Date as table_C_DATE FROM ( [table_A] LEFT JOIN [table_B] ON table_A.DATE <= 日付X AND table_B.DATE <= 日付X ) LEFT JOIN [table_C] ON table_C.DATE <= 日付X

回答No.2

おつかれさまです Oracleならこんな感じかな? でも、実行してませんので直してくださいね。 Select tableA.ID, tableA.DATE as table_A_DATE, tableB.DATE as table_B_DATE, tableC.DATE as table_C_DATE From tableA,tableB,tableC Where tableA.ID = tableB.ID(+) And tableA.ID = tableC.ID(+) And tableA.DATE <= 日付X And tableB.DATE <= 日付X And tableC.DATE <= 日付X

BottleCap
質問者

補足

残念ながらオラクルではなくて こちらはPostgreSQLなんです。 (+)が使えないですが参考にさせて頂きます。 回答ありがとうございました。

  • BellBell
  • ベストアンサー率54% (327/598)
回答No.1

外部結合で実現できると思われます。 ただし、外部結合はSQLの方言のきつい部分なので、データベースサーバがなにか判らないため、そのものずばりを記述するのは、割愛しなきゃ仕方ないですね。 1)A,B,Cそれぞれを、ID番号で外部結合して一つのテーブルのように扱えるようにする 2)Aの日付がX以前であるようにWhereを記述 3)BがNULLであるか、日付がX以前であるようにWhereを記述 4)CがNULLであるか、日付がX以前であるようにWhereを記述 のステップで実行されていけばとりあえず良いかと思います。件数やDBサーバのスペック、接続方法などによっては、チューニングが必要です。 データを並べるだけより、どのような結果を取得したいのかを文章で書いたほうが、回答が得られると思います。 また、記述された例では、当日を含むか含まないかが判りません。実装する際にはそのあたりに気をつけた方が良いと思われます。

参考URL:
http://www.atmarkit.co.jp/fnetwork/rensai/sql06/sql1.html
BottleCap
質問者

補足

回答ありがとうございます。 こちらの使用しているものはPostgreSQLです。 >また、記述された例では、当日を含むか含まないかが判りません。実装する際にはそのあたりに気をつけた方が良いと思われます。 とりあえず、どんな感じのSQLになるのか 知りたくてざっと質問を作ってしまったため 内容がアバウトになっていました・・。 申し訳ないです。