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

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

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

2回答

6481閲覧

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

k499778

総合スコア599

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2016/07/20 15:00

編集2016/07/20 21:40

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

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

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

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

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

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

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

といったように。

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

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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Panzer_vor

2016/07/20 15:56

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

2016/07/20 21:42

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

回答2

0

ベストアンサー

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

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

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

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

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

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

SQL

1SELECT 2 * 3FROM 4 売上表 A 5 INNER JOIN 6( 7SELECT 8 MIN(売上表.顧客CD) 最小顧客CD 9FROM 10 売上表 11WHERE 12 削除フラグ = '0' 13) B ON A.顧客CD = B.最小顧客CD

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

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

投稿2016/07/20 23:15

編集2016/07/20 23:47
Panzer_vor

総合スコア1636

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

k499778

2016/07/20 23:18

回答ありがとうございます。 >削除フラグの立っていない最小の顧客コード取得用のサブクエリをテーブル別名を付けて用意し、 そいつをベースに結合していくのが無難かと思います。 そのようなやり方があるのですね。まだまだ初心者なのですが、もう少しだけ具体的に教えていただくことは可能でしょうか? もちろん自分でも調べます。
k499778

2016/07/21 03:05

追加回答ありがとうございます。 具体的に提示していただいたおかげで非常に理解度があがりました。 SQLに関してまだまだ半人前なのでこれを刺激に精進致します。
guest

0

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

SQL

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

投稿2016/07/20 23:02

A.Ichi

総合スコア4070

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

k499778

2016/07/20 23:05

回答ありがとうございます。 やはりこの書き方になりますかね。 サブクエリというのと他に5箇所ほどこのように書かないといけない場所があるのでパフォーマンス的にどうかなという思いがあります。 回答していただきありがとうございました。参考にさせて頂きます。
A.Ichi

2016/07/20 23:14

ON区に書く意味は最初に件数を絞る事でパフォーマンスを良くすると言う意味だと思いますが、削除flgの参照が無いとインデックスでの検索になり早くなるとは思います。 他の方法で、比較箇所が多いので有れば、minのテーブルとして外出して、JOINする方法のが良いかもしれません
A.Ichi

2016/07/20 23:21

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

2016/07/21 03:06

回答ありがとうございます。 具体的なコードも示していただき非常にわかりやすかったです。 ありがとうございました。助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問