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

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

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

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

Q&A

解決済

1回答

417閲覧

DBの福問い合わせでのEXISTSの挙動

Chandler_Bing

総合スコア673

MySQL

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

0グッド

0クリップ

投稿2019/02/10 10:46

以下の値を返すSQL文があります。(select hotel_id, country_code from areas where area like '%地名%')

hotel_idcountry_code
1PHL
2PHL
3PHL

この結果を以下のテーブルに1行づつ検索をかけていきたいです。(hotelテーブルにもhotel_id,country_codeがある為、一致する行が欲しい)

EXISTSを使い以下の文を実行すると思い通りの値が返ってきます。この挙動について確認したいのですが、これは表示結果の1行が最初に選択され、
それをhotelテーブルの上から順番に問い合わせ、2が一致していれば取り出すというのを今回でいうと上記の3行全てで行なっているという感じですか。

SELECT * FROM hotels WHERE EXISTS (SELECT hotel_id, country_code from areas where area like '%地名%')
CREATE TABLE `hotels` ( `hotel_id` int(11) NOT NULL, `country_code` enum('JPN','PHL') DEFAULT NULL, `hotel_name` varchar(200) NOT NULL, `hotel_address` varchar(200) NOT NULL, `hotel_tel` varchar(100) NOT NULL, `price` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; -- -- Dumping data for table `hotels` -- INSERT INTO `hotels` (`hotel_id`, `country_code`, `hotel_name`, `hotel_address`, `hotel_tel`, `price`) VALUES (1, 'PHL', 'クラウン リージェンシー ホテル & タワーズ (Crown Regency Hotel & Towers)', 'Osmeña Boulevard, セブ シティ, セブ, フィリピン', '63324389294', 20), (2, 'PHL', 'サローサ インターナショナル ホテル & レジデンシャル スイーツ (Sarrosa International Hotel and Residential Suites)', 'Kasambagan, Mabolo, Cebu City, Philippines, セブ シティ, セブ, フィリピン, 6000', '12345678912', 22), (3, 'PHL', 'マルコ ポーロ プラザ セブ ホテル (Marco Polo Plaza Cebu Hotel)', 'Cebu Veterans Drive, Nivel Hills, Apas, セブ シティ, セブ, フィリピン, 6000 - マップで立地をチェック', '12345678912', 30); -- -- Indexes for dumped tables -- -- -- Indexes for table `hotels` -- ALTER TABLE `hotels` ADD PRIMARY KEY (`hotel_id`); -- -- AUTO_INCREMENT for dumped tables -- -- -- AUTO_INCREMENT for table `hotels` -- ALTER TABLE `hotels` MODIFY `hotel_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=4;

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

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

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

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

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

guest

回答1

0

ベストアンサー

EXISTSを使い以下の文を実行すると思い通りの値が返ってきます。

SQL

1SELECT * FROM hotels 2WHERE EXISTS (SELECT hotel_id, country_code from areas where area like '%地名%')

本当ですか?

これは表示結果の1行が最初に選択され、それをhotelテーブルの上から順番に問い合わせ、2が一致していれば取り出すというのを今回でいうと上記の3行全てで行なっているという感じですか。

このSQLは、「areasarea地名を含むものが存在すればhotelsを表示する」という状態です。

意図するものは、以下だと思われます。

SQL

1SELECT * FROM hotels 2WHERE (hotel_id, country_code) in ( 3 SELECT hotel_id, country_code from areas 4 where area like '%地名%' 5 )

追記

上記のexists使用版

SQL

1SELECT * FROM hotels t1 2WHERE exists ( 3 SELECT 1 from areas 4 where hotel_id = t1.hotel_id and country_code = t1.country_code 5 and area like '%地名%' 6 )

投稿2019/02/10 10:55

編集2019/02/10 12:03
sazi

総合スコア25138

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

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

Chandler_Bing

2019/02/10 11:10

たまた上手くいっていただけでした。。。 ありがとうございます。挙動としては1行づつ検索をかけどちらかがヒットすればのような気がします。 今回はhotelのcountry_codeが全てPHLなので1件でも副問い合わせでcountry_codeがPHLのものがあれば全部取り出してきますよね。。。
sazi

2019/02/10 12:08 編集

元のSQLに対するコメントでしょうか? 先に示したSQLは、該当するareasの(hotel_id, country_code)を取り出して該当するhotelsを取得します。 追記したexistsによる相関問合せのSQLは、hotelseの(hotel_id, country_code)と同じで該当するareaが存在するかです。 共に同じ結果です。 hotelseを絞りこむ条件が他にないなら前者の方が多分高速です。
sazi

2019/02/10 12:08

existsを条件に使用する場合、多くは相関問合せです。
Chandler_Bing

2019/02/10 12:13

ありがとうございます。SELECT 1の1をよく見るのですがどういう意味があるのでしょうか。
sazi

2019/02/10 12:56

existsは(True/False)の判断なので、selectの項目は何でもいいのです。 実際の項目名や*にするより値などで指定する方が、実行計画に変な影響を与えないので直接値を指定します。 1を使用する事が多いのは、True=1という意味に掛けているという事だったような。
Chandler_Bing

2019/02/10 14:37

ありがとうございます。これからも精進します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問