質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.83%

[MySQL]JOIN句のonに条件を書きたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,598

k499778

score 542

現在DBはMySQLを使ってデータ取得をしています。

質問があるのですが、
結論から言うと、
結合の際に「顧客CDが一番小さく、かつ削除フラグが0のもの」という条件を設定するにはどうしたらいいでしょうか?

例えば、次のようなテーブルがあるとします。それぞれのテーブルに暗黙的に削除フラグがあるとします。
※削除フラグ(1:有効,0:無効)が有効の場合、そのレコードは論理削除されている。
イメージ説明

これを内部結合したのが以下です。
イメージ説明

これを結合の際に「顧客CDが一番小さく、かつ削除フラグが0のもの」という条件を設定したいのです。

概要設計書では、JOIN句のONの部分にその条件を書くように指示されていました。

ON 売上表.顧客CD = 顧客CDが一番小さいもの


といったように。

またいくつものテーブルを結合しているクエリであり、
「顧客CDが一番小さいもの」のようなJOIN句のONの条件が他にも5つほどあるので
パフォーマンスを考えたクエリにしたいと思っています。
パフォーマンスが良く、シンプルな書き方にするにはどのような書き方にすればよいでしょうか?

もしわかる方がいればお願い致します。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Panzer_vor

    2016/07/21 00:56

    「顧客コードが最も小さい」という条件ですが、どのテーブルが基準となりますでしょうか?
    例示にある顧客表と売上表では最小は必ずしも一致しないはずなので、中心をどちらにするかで結果は変わってきます。

    キャンセル

  • k499778

    2016/07/21 06:42

    回答有り難うございます。
    修正いたしました。
    売上表テーブルを基準とします。

    キャンセル

回答 2

checkベストアンサー

+1

結合条件内で集計関数は使えないので、やはりサブクエリを利用せざるをえないです。

①同様の条件が複数登場すること
②売上表のデータ顧客CD以外も当然利用すること

上記2点を考慮すると、
削除フラグの立っていない最小の顧客コード取得用のサブクエリをテーブル別名を付けて用意し、
そいつをベースに結合していくのが無難かと思います。

クエリ全体の見た目はパッとしませんがね。

MySQL以外のDBMSだとWITH句をサポートしてるので、
クエリ自体はもう少しすっきり書けそうな気はするのですが^^;

追記
イメージとしては以下のような感じです。

SELECT
    *
FROM
    売上表 A 
    INNER JOIN
(
SELECT
    MIN(売上表.顧客CD) 最小顧客CD
FROM
    売上表
WHERE
    削除フラグ = '0'
) B ON A.顧客CD = B.最小顧客CD

後は上記を膨らませていく感じです。

追記②
ソース修正しました。
寝ぼけてどえらいコード書いてました……

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/21 08:18

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

    >削除フラグの立っていない最小の顧客コード取得用のサブクエリをテーブル別名を付けて用意し、
    そいつをベースに結合していくのが無難かと思います。

    そのようなやり方があるのですね。まだまだ初心者なのですが、もう少しだけ具体的に教えていただくことは可能でしょうか?

    もちろん自分でも調べます。

    キャンセル

  • 2016/07/21 12:05

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

    具体的に提示していただいたおかげで非常に理解度があがりました。

    SQLに関してまだまだ半人前なのでこれを刺激に精進致します。

    キャンセル

+1

ONの中に押し込むのは難しいですね、取り合えず

select * from 売上表 join 顧客表 on 売上表.顧客CD=顧客表.顧客cd
and 顧客表.顧客cd=(select min(顧客cd) from 顧客表 where 削除fulg=0)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/21 08:05

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

    やはりこの書き方になりますかね。
    サブクエリというのと他に5箇所ほどこのように書かないといけない場所があるのでパフォーマンス的にどうかなという思いがあります。

    回答していただきありがとうございました。参考にさせて頂きます。

    キャンセル

  • 2016/07/21 08:14

    ON区に書く意味は最初に件数を絞る事でパフォーマンスを良くすると言う意味だと思いますが、削除flgの参照が無いとインデックスでの検索になり早くなるとは思います。

    他の方法で、比較箇所が多いので有れば、minのテーブルとして外出して、JOINする方法のが良いかもしれません

    キャンセル

  • 2016/07/21 08:21

    一応
    select 売上表.*, 顧客表.* from 売上表 join 顧客表 on 売上表.顧客CD=顧客表.顧客cd
    join (select min(顧客cd) 顧客cd from 顧客表 where 削除fulg=0) TB1 on 顧客表.顧客cd=TB1.顧客cd;

    キャンセル

  • 2016/07/21 12:06

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

    具体的なコードも示していただき非常にわかりやすかったです。

    ありがとうございました。助かりました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.83%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る