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

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

解決済

3回答

4862閲覧

1度のSQLで結合条件によって結果を変化させたい

enigumalu

総合スコア192

MySQL

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

SQL

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

0グッド

1クリップ

投稿2016/12/21 10:58

SQLで特定のテーブル同士のデータを見て、一致した場合、一致した値で検索を行い、
1つも一致しなかった場合結合判定を無視して検索を行いたいのですが
そういったことは可能でしょうか?
JOINやEXISTSを使うと結合条件に一致しない場合、結果がからになってしまうので困っています。

SELECT * FROM test_data td
....
EXISTS (
SELECT * FROM test_cond tc WHERE tc.u_cd = td.u_cd
)
使用しているDBはMySql5.6 利用可能なプログラムはPHPです。
プログラムを用いる方法の場合でも2回sqlを発行できないのでご教授いただけますと幸いです。

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

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

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

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

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

Panzer_vor

2016/12/21 11:27

要件の確認です。id同士で一致するデータがある場合は対象のtest_dataだけを、なければtest_data全件とりたいということで相違ないでしょうか?
enigumalu

2016/12/21 11:41

相違ないです基本的には全権取得出来、絞込みテーブルのtest_condに同一コードのデータがある場合は絞り込まれるといった感じです。
guest

回答3

0

JOINやEXISTSを使うと結合条件に一致しない場合、結果がからになってしまうので困っています。

JOINを使うと結合条件に一致しない場合に空になるというのが判然としませんでした。
他の条件の兼ね合いでそうなるってことでしょうか。
LEFT JOINではダメなのですか…?
結合判定を無視するための条件は大抵LEFT JOINで済むと思うのですが…

IF句を使うのはどうでしょうか。

空で書いてるので自信がありませんが…下記のようなクエリです。

SQL

1IF EXISTS(SELECT * FROM test_data td INNER JOIN test_cond tc ON tc.u_cd = td.u_cd) THEN 2 SELECT * FROM test_data td WHERE EXISTS(SELECT * FROM test_cond tc WHERE tc.u_cd = td.u_cd) 3ELSE 4 SELECT * FROM test_data td 5END IF;

投稿2016/12/22 01:43

編集2016/12/22 01:45
haru666

総合スコア1591

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

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

enigumalu

2016/12/29 06:09

プロシージャが一番直感的な記述になったと思うので今度試してみます。 すでに存在する物が正のためやむなく使用できないのです。
guest

0

たとえばこんな感じ

SQL

1create table tbl_a(id int not null ,unique(id),val int); 2create table tbl_b(id int not null ,unique(id)); 3create table tbl_c(id int not null ,unique(id)); 4insert into tbl_a values(1,100),(2,200),(3,250); 5insert into tbl_b values(2),(3),(4); 6insert into tbl_c values(4),(5),(6);

考え方

  • joinしてcount(*)>0ならjoinしたものを表示
  • count(*)=0ならtbl_aだけ
  • 上記2条件は完全に競合する内容なので、両方実行してUNIONする

結果

SQL

1select tbl_a.* from tbl_a inner join tbl_b on tbl_a.id=tbl_b.id 2group by id having count(*)>0 3union all 4select * from tbl_a where( 5select count(*) from tbl_a inner join tbl_b on tbl_a.id=tbl_b.id 6)=0; 7 8select tbl_a.* from tbl_a inner join tbl_c on tbl_a.id=tbl_c.id 9group by id having count(*)>0 10union all 11select tbl_a.* from tbl_a where( 12select count(*) from tbl_a inner join tbl_c on tbl_a.id=tbl_c.id 13)=0; 14

投稿2016/12/22 01:28

yambejp

総合スコア114769

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

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

0

ベストアンサー

実行効率は隅に置いていますが、
一先ず以下のようなイメージでやりたいことは行えるのではないでしょうか。

SQL

1SELECT  2 td.*  3FROM  4 test_data td 5 LEFT JOIN test_cond tc 6 ON tc.u_id = td.u_id 7 CROSS JOIN ( 8 SELECT 9 CASE 10 WHEN COUNT(*) > 0 THEN 1 11 ELSE 0 12 END AS found 13 FROM 14 test_cond t1 15 INNER JOIN test_data t2 16 ON t1.u_id = t2.u_id 17 ) t 18WHERE 19 td.u_id = 20 CASE 21 WHEN t.found = 1 THEN tc.u_id 22 ELSE td.u_id 23 END

検証は行ってないので、
動かなかったらすみません・・・^^;

上記コードがやってることとしては、
サブクエリ(内側のSELECT句)で、
「test_data」「test_cond」、どちらにも存在するデータ数を取り、
擬似的にフラグ(found)を取得してます。

そのフラグの値によって、
抽出条件(WHERE句)を制御しています。
一致するデータがあれば(found=1)外部結合条件と同様の条件で絞るため、
動きとしては内部結合と一致します。
逆に一致データがない場合(found=1以外)は、
同一のカラム値を比較し通常はTRUEになるため、
全件取得する動作となります。

上記で通常はTRUEとなると書きましたが、
NULLが混入している場合はそうはいかない点に注意してください。
(恐らく主キーだと思われるので、NULL値はあり得ないと踏んではいますが・・・)

ご参考までに。

投稿2016/12/21 12:18

編集2016/12/21 12:27
Panzer_vor

総合スコア1636

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

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

enigumalu

2016/12/29 06:06

ありがとうございます、イメージに近かったのでベストアンサーにしました。 複合主キーですがNULLはないはずなので。 大きいsqlの一部なので600msほど実行が遅くなったりましたがすでに重いため問題ないです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問