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

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

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

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

Q&A

解決済

3回答

1134閲覧

SQLで複数行にマッチする結果を抽出したい

n-o-n

総合スコア7

SQL

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

0グッド

0クリップ

投稿2020/06/10 03:03

編集2020/06/10 03:06

環境

mariadb:10.4

わからないこと

3つの多対多のテーブルがあります。

sql

1SELECT * FROM address;

イメージ説明

sql

1SELECT * FROM type;

イメージ説明

sql

1SELECT * FROM address_type;

イメージ説明

addressとtypeはどちらも増えていきます。

やりたいこと(抽出条件)

address.nameが'a1@d1','a4@d1','a5@d1','a6@d1'であること
かつ
address_type.type_idが1と3だけを持つもの。

テストデータですと、'a4@d1'だけを抽出したいです。

やったこと

sql

1SELECT * FROM address_type t left outer join address a on t.address_id = a.id 2WHERE 3 a.name IN ('a1@d1','a4@d1','a5@d1','a6@d1') 4 -- AND (t.type_id = 1 AND t.type_id=3); -- これだとなにも出力されない

上記を考えたのですがダメでした。。

どうしたらいいのか。。。困っています。。

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

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

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

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

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

sousuke

2020/06/10 04:24 編集

address_type.type_idが1と3だけを持つもの。 に関して1だけ、3だけの場合は対象になるのですか? 例えばaddress_id:7,type_id:1の1行だけみたいなパターンは? あ、1とかがそのパターンでしたね。1と3の両方が必要ということで理解しました。
guest

回答3

0

まず、type側の条件を満たすクエリを作ります。
address_idごとにtype_idが1,3の行hastypeとtype_idが1,3以外の行hasnottype集計するクエリq1を作成します。
条件に合致するパターンは、hastype=2,hasnottype=0となるはずです。

次にaddress.name側の条件を満たすクエリを作ります。
その際、q1からhastype=2,hasnottype=0を満たすaddress_idが存在するかexistsで確かめればよいでしょう。

sql

1with q1 as ( 2 select DISTINCT 3 address_id 4 ,sum(case when type_id in (1,3) then 1 else 0 end) over(partition by address_id) hastype 5 ,sum(case when type_id not in (1,3) then 1 else 0 end) over(partition by address_id) hasnottype 6 from address_type 7) 8select tbl1.name from address tbl1 9where tbl1.name in ('a1@d1','a4@d1','a5@d1','a6@d1') 10 and exists( 11 select address_id 12 from q1 13 where hastype = 2 and hasnottype = 0 14 and tbl1.id = q1.address_id 15 ) 16;

case式でいろんなことができます。参考リンクをぜひ熟読してください。
CASE式のススメ

投稿2020/06/10 03:41

hope_mucci

総合スコア4447

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

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

n-o-n

2020/06/10 05:17

CASE式とっても便利ですね!勉強になります! ありがとうございます!
guest

0

ベストアンサー

1,3を1 以外を9に置き換え、加算した結果が2になるものを抽出

SQL

1SELECT * 2FROM address_type t left outer join address a on t.address_id = a.id 3WHERE a.name IN ('a1@d1','a4@d1','a5@d1','a6@d1') 4 AND t.address_id in ( 5 select address_id 6 from address_type 7 group by address_id 8 having sum(case when type_id in (1,3) then 1 else 9 end)=2 9 )

投稿2020/06/10 03:22

編集2020/06/10 03:55
sazi

総合スコア25195

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

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

sousuke

2020/06/10 03:34

これだとa6も入ると思います。
sazi

2020/06/10 03:54

ですね。 訂正しました。
n-o-n

2020/06/10 05:15

こんなやり方があったんですね!!助かりました! ありがとうございます!!
guest

0

高速回答ありがとうございます!

実際にいただいた2つのSQL動作を確認させていただいたのですが、
'a6@d1'もひっかかってしまいます。。

投稿2020/06/10 03:31

n-o-n

総合スコア7

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問