前提条件
以下のような「articlesテーブル」、「roomsテーブル」、「facilities_traitテーブル」があるとします。
articles.table
id | flag | title |
---|---|---|
101 | 2 | ××アパート |
102 | 1 | 〇〇マンション |
103 | 2 | △マンション |
: | : | : |
rooms.table
id | flag | status | articles_id |
---|---|---|---|
1 | 2 | 2 | 101 |
2 | 1 | 2 | 101 |
3 | 2 | 2 | 102 |
4 | 1 | 2 | 103 |
5 | 2 | 1 | 103 |
6 | 2 | 1 | 103 |
: | : | : | : |
facilities_trait.table
id | flag | type | trait_id | facilities_id |
---|---|---|---|---|
1 | 2 | 1 | 101 | 12 |
2 | 2 | 1 | 101 | 30 |
3 | 2 | 2 | 1 | 31 |
4 | 2 | 1 | 102 | 12 |
5 | 2 | 1 | 102 | 30 |
6 | 2 | 1 | 103 | 12 |
7 | 2 | 2 | 3 | 28 |
8 | 2 | 1 | 103 | 30 |
9 | 2 | 2 | 3 | 31 |
10 | 2 | 1 | 104 | 30 |
11 | 2 | 2 | 4 | 31 |
12 | 2 | 3 | 105 | 25 |
13 | 2 | 1 | 105 | 30 |
14 | 2 | 2 | 5 | 31 |
15 | 2 | 2 | 6 | 27 |
16 | 2 | 1 | 106 | 30 |
facilities_traitテーブルのtrait_idにはarticles.id
とrooms.id
が混在していて、typeでarticlesかroomsか判別しています。
実装したいこと
1.
まず、facilities_traitテーブルのfacilities_id = 31
を持つ trait_id を全て取り出します。
facilities_trait.table
id | flag | type | trait_id | facilities_id |
---|---|---|---|---|
3 | 2 | 2 | 1 | 31 |
9 | 2 | 2 | 3 | 31 |
11 | 2 | 2 | 4 | 31 |
14 | 2 | 2 | 5 | 31 |
2.
type = 2
なのでroomsテーブルを見て、facilities.trait_id = rooms.id
で紐づくものを取り出します。
rooms.table
id | flag | status | articles_id |
---|---|---|---|
1 | 2 | 2 | 101 |
3 | 2 | 2 | 102 |
4 | 1 | 2 | 103 |
5 | 2 | 1 | 103 |
その際rooms.flag = 2
,rooms.status = 2
以外のものは除外します。
rooms.table
id | flag | status | articles_id |
---|---|---|---|
1 | 2 | 2 | 101 |
3 | 2 | 2 | 102 |
3.
articlesテーブルでrooms.articles_id
に紐づくものを取り出します。
articles.table
id | flag | title |
---|---|---|
101 | 2 | ××アパート |
102 | 1 | 〇〇マンション |
その際articles.flag = 2
以外のものは除外します。
articles.table
id | flag | title |
---|---|---|
101 | 2 | ××アパート |
4.
articles.id
をもって改めてfacilitiesテーブルに戻り、articles.id = facilities_trait.trait_id
を取り出します。
facilities_trait.table
id | flag | type | trait_id | facilities_id |
---|---|---|---|---|
1 | 2 | 1 | 101 | 12 |
2 | 2 | 1 | 101 | 30 |
ここで、facilities_traitテーブルのflag = 2
type = 1 OR type = 3
の条件に合致するものを抽出したいです。
最終的に欲しい結果
facilities_trait.table
id | flag | type | trait_id | facilities_id |
---|---|---|---|---|
1 | 2 | 1 | 101 | 12 |
2 | 2 | 1 | 101 | 30 |
現状のコード
分かりやすさを優先させましたが、facilities_trait.trait_id
に入るarticlesとroomsのidは被る可能性があります(その為のtypeでもあります)。
SELECT * FROM facilities_trait WHERE flag = 2 AND (type = 1 OR type = 3) AND EXISTS( SELECT 'X' FROM articles WHERE flag = 2 AND facilities_trait.trait_id = articles.id AND EXISTS( SELECT 'X' FROM rooms WHERE flag = 2 AND status = 2 AND rooms.articles_id = articles.id AND EXISTS( SELECT 'X' FROM facilities_trait WHERE rooms.id = facilities_trait.trait_id AND facilities_trait.facilities_id = 31)))
ひとまずは上記のコードで目的の結果は得られておりました。
ただ、クエリがすごく重たいのでINNER JOIN
等で書き換えたいと思っております。
皆様の知恵をお借りしたいです。
宜しくお願い致します。
回答2件
あなたの回答
tips
プレビュー