人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

MySQLのJOINの結合方法で再度質問です。

前回の質問
http://q.hatena.ne.jp/1195028480
でテーブル同士のフィールドをチェックし、出力する方法を教えていただきました。

そして
SELECT * FROM b_table AS b LEFT JOIN a_table AS a on (b.money>=a.money_s AND b.money<=a.money_b AND b.tax=a.tax) WHERE b.money is not null ORDER BY a.a_table_id

というようにすると、aテーブル(条件設定)で指定した条件に合ったbテーブル(料金表)のレコードを抽出出来るようになりました。

そこで質問ですが、aテーブルのtaxに値が入っていないレコードは結合条件を
(b.money>=a.money_s AND b.money<=a.money_b)

としたいのですが、そのような事は可能でしょうか?
(つまり、aテーブルに入力されている条件が、2つの場合・3つの場合(レコード毎で異なる場合)でも出力できるようにしたい)

SQL文を分けて2つ書けば出来るでしょうが、あくまで「1つのSQL文で出来る場合」を教えて下さい。もし、不可能ならそれで納得します。


MySQLは4.0.26を使っています。その他のバージョンで上記の事が可能なら教えて下さい。


●質問者: kt26
●カテゴリ:ウェブ制作
✍キーワード:AS MySQL ON SELECT SQL
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● chuken_kenkou
●20ポイント

前回の質問の回答は、LEFT JOINにする必要はなく、INNER JOINでよかったですね。失礼しました。

WHERE b.money is not null 

a_tableをLEFT JOINするのだから、a_tableのキー列でないと意味がないですが?

以下のSQLで、前回の期待した結果と同じ結果が得られると思います。

SELECT * FROM b_table AS b 
 INNER JOIN a_table AS a
 ON (b.money>=a.money_s AND b.money<=a.money_b AND b.tax=a.tax) 
 ORDER BY a.a_table_id

それで今回の要件に関してですが、今回はLEFT JOINを使う方法になります。

以下のSQLでいかがでしょうか?

SELECT * FROM b_table AS b
 LEFT JOIN a_table AS a 
 ON (b.money>=a.money_s AND b.money<=a.money_b AND b.tax=a.tax) 
 WHERE a.money_s IS NOT NULL AND a.money_b IS NOT NULL 
 ORDER BY a.a_table_id

MySQL AB :: MySQL 4.1 リファレンスマニュアル :: 6.4.1.1 JOIN 構文

◎質問者からの返答

すみません、ちょっと質問の意味と違うような…。


三番目の例は私が質問で出した例の、WHEREの部分に追加していただいて、money_sとmoney_bがNULLでない場合を条件にしていますよね?(ちなみに、b.money is not nullとなっているのは、コピペミスです。すみません)


そうではなくて、例えば

b.tax=a.tax

は、bテーブルのtaxとaテーブルのtaxが一致するものを表示するという条件ですが、「aテーブルの対象レコードにtaxの値が無い場合、この部分を避けたい」と言うのが希望です。


money_sとmoney_bしか入力していない場合は「b.money>=a.money_s AND b.money<=a.money_b」という結合条件を、money_sとmoney_bとtaxを入力している場合は「b.money>=a.money_s AND b.money<=a.money_b AND b.tax=a.tax」と言う結合条件を


という、IFみたいな事が出来ないかと思い、相談させて頂きました。


{追記}

ちょっとわかりづらいかもしれませんので、、結果として以下のような出力が出来ればと思っています。

AのID Bの料金Aの範囲Aのtax
1 100 50?150 1
2 100 100?200

※Bテーブルにはmoney「100」とtax「1」が入っている


2 ● chuken_kenkou
●100ポイント

aテーブルの対象レコードにtaxの値が無い場合

これは、Aのtaxはnullと考えていいでしょうか?

もしそうなら、「or a.tax is null」といった条件を追加する方法が、よく行われると思います。

select * from b_table as b
 left join a_table as a
 on b.money>=a.money_s and b.money<=a.money_b
 and (b.tax=a.tax or a.tax is null) 
 order by a.a_table_id

http://q.hatena.ne.jp/ダミーです

◎質問者からの返答

ありがとうございます。こういうやり方があるんですね。当初の目的としてはうまくできました。


ただ、別質問にした方が良いかもしれないんですが、IFみたいな事って出来ませんかね?

aテーブルに「種類(type)」と言うのを追加して、

typeが1なら結合条件は「b.money>=a.money_s and b.money<=a.money_b and b.tax=a.tax」になる。
typeが2なら「b.money>=a.money_s and b.money<=a.money_b」

のような。

MySQLでIFを使えるのは知っていますが、回答していただいたSQL文に果たしてIFを組み込み、

私が思っているような条件分岐が出来るものだろうか?もし出来たらより汎用性が広がる


と思っています。何度もすみませんが、もしご存じでしたら、教えていただければと思います。


3 ● chuken_kenkou
●100ポイント

希望の操作ができる検索条件例です。

where b.money>=a.money_s and b.money<=a.money_b 
 and (b.tax=a.tax and type=1 or type=2)

RDBMSは、インデクスの定義と、検索条件、ORDER BYやGROUP BY、DISTINCTといった指定等の

組み合わせから、なるべく最適なアクセス計画を作ろうとします。

そのため、DB操作に直接関係しない検索条件を、SQL中に指定可能だからといって、指定していいか?」

ということも考える必要があります。

今回の場合は、typeを含めると、(money,tax,type)という列構成のインデクスがあり、データ件数が

1000件以上くらいなら、インデクスがない場合に比べ、差が出るかもしれません。

データ件数が多くても1000件程度なら、それ程、気にする必要はないですけどね。

◎質問者からの返答

ありがとうございます。非常に参考になりました。

また、コメントの件もさんこうにさせていただきます。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ