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

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

解決済

4回答

1301閲覧

SQL文の検索について

Chandler_Bing

総合スコア673

MySQL

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

SQL

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

0グッド

0クリップ

投稿2019/02/28 11:37

SQL

1SELECT * FROM hotels JOIN hotels_tags ON hotels.hotel_id = hotels_tags.hotel_id AND hotels.country_code = hotels_tags.country_code JOIN tags ON hotels_tags.tags_id = tags.tags_id

以下の三つのtabelをこのSQLで繋げます。
tagsに'朝食付き'と'キャンセル無料'がありますが、これをWHWER句で検索対象に指定した場合、上記の全て繋げたSQLに対して1つのホテルが
その両方のタグを持っている場合のみ取り出すというのはどうすれば良いですか。

SQL

1SELECT * FROM hotels JOIN hotels_tags ON hotels.hotel_id = hotels_tags.hotel_id AND hotels.country_code = hotels_tags.country_code JOIN tags ON hotels_tags.tags_id = tags.tags_id 2WHERE tags.tag = '朝食付き' AND tags.tag = 'キャンセル無料'

こうすると1行づつ見ていくので、タグが複数になった時点で、ヒットしませんし、ORにすると期待値とは異なります。どう検索をかければ良いですか。

SQL

1CREATE TABLE `hotels` ( 2 `hotel_id` int(11) NOT NULL, 3 `country_code` enum('JPN','PHL') DEFAULT NULL, 4 `hotel_name` varchar(200) NOT NULL, 5 `hotel_address` varchar(200) NOT NULL, 6 `hotel_tel` varchar(100) NOT NULL, 7 `price` int(11) NOT NULL, 8 `likes` varchar(100) NOT NULL 9) ENGINE=InnoDB DEFAULT CHARSET=utf8; 10 11 12INSERT INTO `hotels` (`hotel_id`, `country_code`, `hotel_name`, `hotel_address`, `hotel_tel`, `price`, `likes`) VALUES 13(1, 'PHL', 'クラウン リージェンシー ホテル & タワーズ (Crown Regency Hotel & Towers)', 'Osmeña Boulevard, セブ シティ, セブ, フィリピン', '63324389294', 30, '279'), 14(2, 'PHL', 'サローサ インターナショナル ホテル & レジデンシャル スイーツ (Sarrosa International Hotel and Residential Suites)', 'Kasambagan, Mabolo, Cebu City, Philippines, セブ シティ, セブ, フィリピン, 6000', '12345678912', 22, '300'), 15(3, 'PHL', 'マルコ ポーロ プラザ セブ ホテル (Marco Polo Plaza Cebu Hotel)', 'Cebu Veterans Drive, Nivel Hills, Apas, セブ シティ, セブ, フィリピン, 6000 - マップで立地をチェック', '12345678912', 20, '893'), 16(4, 'PHL', 'Express Inn Cebu Mabolo', 'M.J. Cuenco Avenue corner Pope John Paul II, セブ シティ, セブ, フィリピン, 6000', '87634516783', 40, '0'), 17(5, 'PHL', 'レッド プラネット セブ (Red Planet Cebu)', '36 Archbishop Reyes Avenue, セブ シティ, セブ, フィリピン', '98765432123', 6, '12'), 18(6, 'PHL', 'リッチモンド プラザ ホテル (Richmond Plaza Hotel)', 'F. Sotto Drive Gorordo Avenue, セブ シティ, セブ, フィリピン', '49316491673', 35, '0'), 19(7, 'PHL', 'ザ NS ロイヤル ホテル (The NS Royal Hotel)', 'Juana Osmeña Street, セブ シティ, セブ, フィリピン', '58732614881', 23, '11'), 20(8, 'PHL', 'パーム グラス ホテル (Palm Grass Hotel)', '68 JUNQUERA STREET, セブ シティ, セブ, フィリピン', '47329864931', 12, '23'), 21(9, 'PHL', 'ベストセラーウォーターフロント セブ シティ ホテル アンド カジノ (Waterfront Cebu City Hotel and Casino)', 'Salinas Drive Lahug, セブ シティ, セブ, フィリピン', '59457884901', 21, '13'), 22(10, 'PHL', '\r\nドルシネア ホテル & スイーツ (Dulcinea Hotel and Suites)', 'Shangs Mactan Town Center, M.L Quezon National Highway Pajo, Lapu-Lapu City, マクタン島, セブ, フィリピン', '47153645137', 11, '33'), 23(11, 'PHL', 'ゴールデン プリンス ホテル & スイート (Golden Prince Hotel & Suites)', 'Acacia Street Corner Archbishop Reyes Avenue, セブ シティ, セブ, フィリピン', '98312563651', 10, '12'), 24(12, 'PHL', 'マンダリン プラザ ホテル (Mandarin Plaza Hotel)', 'Archbishop Reyes Corner Escario Street, セブ シティ, セブ, フィリピン', '64687645354', 36, '22'); 25 26ALTER TABLE `hotels` 27 ADD PRIMARY KEY (`hotel_id`), 28 ADD UNIQUE KEY `hotel_id` (`hotel_id`,`country_code`); 29 30ALTER TABLE `hotels` 31 MODIFY `hotel_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=13;

SQL

1CREATE TABLE `tags` ( 2 `tags_id` int(11) NOT NULL, 3 `tag` varchar(100) NOT NULL, 4 `tag_kind` enum('payment','service','equipment','internet','relaxation','language','location') DEFAULT NULL, 5 `display` enum('1','0') NOT NULL 6) ENGINE=InnoDB DEFAULT CHARSET=utf8; 7 8 9INSERT INTO `tags` (`tags_id`, `tag`, `tag_kind`, `display`) VALUES 10(1, '無料Wi-Fi', 'internet', '1'), 11(2, '朝食付き', 'service', '1'), 12(3, 'キャンセル無料', 'payment', '1'), 13(4, '宿泊施設へ直接支払い', 'payment', '1'), 14(5, '日本語対応', 'service', '0'), 15(6, '無料送迎', 'service', '0'), 16(7, '後日支払い可', 'payment', '1'), 17(8, 'ツインベット', 'equipment', '0'), 18(9, '禁煙', 'service', '0'), 19(10, '24時間対応フロントデスク', 'service', '0'), 20(11, 'スパ', 'relaxation', '0'), 21(12, 'プール', 'relaxation', '0'), 22(13, '全室無料Wi-Fi', 'internet', '0'), 23(14, 'シャワー付き', 'equipment', '0'), 24(15, 'テレビ放送', 'equipment', '0'), 25(16, '冷蔵庫', 'equipment', '0'), 26(17, 'ルームサービス', 'service', '0'), 27(18, 'フィリピン語', 'language', '0'), 28(19, '北京語', 'language', '0'), 29(20, '英語', 'language', '0'), 30(21, 'クレジットカード不要', 'payment', '1'), 31(22, 'コンビニ', 'location', '0'), 32(23, 'ランドリー', 'location', '0'), 33(24, 'レストラン', 'location', '0'), 34(25, 'デリバリーサービス', 'service', '0'), 35(26, 'ホテル内レストラン', 'service', '0'), 36(27, '洋服掛け', 'equipment', '0'), 37(28, 'ペット可', 'service', '0'); 38 39ALTER TABLE `tags` 40 ADD PRIMARY KEY (`tags_id`), 41 ADD UNIQUE KEY `tag` (`tag`); 42 43ALTER TABLE `tags` 44 MODIFY `tags_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=29;

SQL

1CREATE TABLE `hotels_tags` ( 2 `hotels_tags_id` int(11) NOT NULL, 3 `hotel_id` int(11) NOT NULL, 4 `country_code` enum('JPN','PHL') DEFAULT NULL, 5 `tags_id` int(11) NOT NULL 6) ENGINE=InnoDB DEFAULT CHARSET=utf8; 7 8 9 10INSERT INTO `hotels_tags` (`hotels_tags_id`, `hotel_id`, `country_code`, `tags_id`) VALUES 11(24, 1, 'PHL', 1), 12(41, 1, 'PHL', 2), 13(42, 1, 'PHL', 3), 14(25, 1, 'PHL', 4), 15(43, 1, 'PHL', 5), 16(44, 1, 'PHL', 6), 17(26, 1, 'PHL', 7), 18(27, 1, 'PHL', 8), 19(28, 1, 'PHL', 9), 20(29, 1, 'PHL', 10), 21(45, 1, 'PHL', 11), 22(46, 1, 'PHL', 12), 23(51, 1, 'PHL', 13), 24(30, 1, 'PHL', 14), 25(31, 1, 'PHL', 15), 26(32, 1, 'PHL', 16), 27(52, 1, 'PHL', 18), 28(53, 1, 'PHL', 19), 29(54, 1, 'PHL', 20), 30(97, 1, 'PHL', 27), 31(33, 2, 'PHL', 1), 32(34, 2, 'PHL', 3), 33(35, 2, 'PHL', 5), 34(36, 2, 'PHL', 8), 35(37, 2, 'PHL', 10), 36(38, 2, 'PHL', 13), 37(39, 2, 'PHL', 16), 38(40, 2, 'PHL', 17), 39(93, 2, 'PHL', 22), 40(1, 3, 'PHL', 1), 41(2, 3, 'PHL', 2), 42(3, 3, 'PHL', 3), 43(4, 3, 'PHL', 4), 44(6, 3, 'PHL', 5), 45(7, 3, 'PHL', 6), 46(5, 3, 'PHL', 7), 47(8, 3, 'PHL', 8), 48(9, 3, 'PHL', 9), 49(10, 3, 'PHL', 10), 50(11, 3, 'PHL', 11), 51(12, 3, 'PHL', 12), 52(13, 3, 'PHL', 13), 53(14, 3, 'PHL', 14), 54(15, 3, 'PHL', 15), 55(22, 3, 'PHL', 16), 56(23, 3, 'PHL', 17), 57(95, 3, 'PHL', 21), 58(96, 3, 'PHL', 27), 59(94, 3, 'PHL', 28), 60(55, 4, 'PHL', 1), 61(56, 4, 'PHL', 3), 62(57, 4, 'PHL', 5), 63(58, 4, 'PHL', 6), 64(73, 4, 'PHL', 7), 65(59, 4, 'PHL', 8), 66(60, 4, 'PHL', 9), 67(61, 4, 'PHL', 10), 68(62, 4, 'PHL', 11), 69(65, 4, 'PHL', 12), 70(66, 4, 'PHL', 13), 71(67, 4, 'PHL', 14), 72(68, 4, 'PHL', 15), 73(69, 4, 'PHL', 16), 74(70, 4, 'PHL', 17), 75(71, 4, 'PHL', 18), 76(72, 4, 'PHL', 20), 77(74, 5, 'PHL', 1), 78(75, 5, 'PHL', 3), 79(76, 5, 'PHL', 6), 80(77, 5, 'PHL', 7), 81(78, 5, 'PHL', 8), 82(79, 5, 'PHL', 9), 83(80, 5, 'PHL', 10), 84(81, 5, 'PHL', 13), 85(82, 5, 'PHL', 14), 86(83, 5, 'PHL', 15), 87(84, 5, 'PHL', 17), 88(85, 5, 'PHL', 18), 89(86, 5, 'PHL', 20), 90(87, 5, 'PHL', 21), 91(88, 5, 'PHL', 22), 92(89, 5, 'PHL', 24), 93(90, 5, 'PHL', 26), 94(98, 6, 'PHL', 1), 95(99, 6, 'PHL', 2), 96(100, 6, 'PHL', 3), 97(101, 6, 'PHL', 4), 98(102, 6, 'PHL', 5), 99(103, 6, 'PHL', 8), 100(104, 6, 'PHL', 9), 101(105, 6, 'PHL', 10), 102(106, 6, 'PHL', 13), 103(107, 6, 'PHL', 14), 104(108, 6, 'PHL', 15), 105(109, 6, 'PHL', 16), 106(110, 6, 'PHL', 17), 107(111, 6, 'PHL', 18), 108(112, 6, 'PHL', 19), 109(113, 6, 'PHL', 20), 110(114, 6, 'PHL', 22), 111(115, 6, 'PHL', 23), 112(116, 6, 'PHL', 24), 113(117, 6, 'PHL', 25), 114(118, 6, 'PHL', 26), 115(119, 6, 'PHL', 27); 116 117ALTER TABLE `hotels_tags` 118 ADD PRIMARY KEY (`hotels_tags_id`), 119 ADD UNIQUE KEY `hotel_id` (`hotel_id`,`country_code`,`tags_id`); 120 121ALTER TABLE `hotels_tags` 122 MODIFY `hotels_tags_id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=255; 123

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

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

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

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

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

Orlofsky

2019/02/28 11:54 編集

質問に載せる内容は、聞きたいことを説明できる最低限の情報に絞っては? 雑音が多過ぎ。
m.ts10806

2019/02/28 13:03

tabelって何でしょ
sazi

2019/02/28 13:15

@Orlofskyさん 雑音ってどの情報ですか?
Orlofsky

2019/03/01 14:38

saziさんって、確信犯でしょうか? 質問のSELECT文を実行できる必要最小限のカラムに絞らないと質問者は問題点をきちんと把握できないでしょう。無駄にデータが多いのも質問者が問題を理解する妨げにしかなっていないかと。
sazi

2019/03/02 08:32 編集

雑音というのは、直接関係のないデータという事ですか。 必要なカラムはselet文で分かりますから、質問に記載するスクリプトについては、コピペして流すだけですし、過剰と言われる部分は気にはなりませんでした。 よくコメントされている、create table とデータについて、質問者は記載しているのに、それで雑音と言われたら混乱してしまうと思ったんですよ。
guest

回答4

0

ベストアンサー

選択したtagをパラメータとして渡しやすくなるようにしてみました。
指定したtagを集計した場合に、そのtagの数が指定したtagの数と一致するものがand条件と同じになります。

SQL

1SELECT * FROM hotels 2where (hotel_id, country_code) in ( 3 select hotel_id, country_code 4 from hotels_tags inner join tags 5 on hotels_tags.tags_id = tags.tags_id 6 where tag in ('朝食付き', 'キャンセル無料') 7 group by hotel_id, country_code 8 having count(*)=2 9 )

count(*)と比較している数を、条件のtagの数と合わせる必要があります。

追記

hotelsのプライマリーはhotel_idなので、訂正。
※定義でなんで(hotel_id, country_code)をユニークにしているのか不明ですが。
前者と結果は変わらないと思いますが、簡潔なので。

SQL

1SELECT * FROM hotels 2where hotel_id in ( 3 select hotel_id 4 from hotels_tags inner join tags 5 on hotels_tags.tags_id = tags.tags_id 6 where tag in ('朝食付き', 'キャンセル無料') 7 group by hotel_id 8 having count(*)=2 9 )

投稿2019/02/28 12:18

編集2019/02/28 12:39
sazi

総合スコア25184

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

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

sazi

2019/02/28 12:27

momon-gaさんのをそのままんま展開した形ですねw
sazi

2019/02/28 12:43

甘いでしょうか。成長されている印象ですけど。
m.ts10806

2019/02/28 13:04

この内容理解して使うのならいいんですが。
sazi

2019/02/28 13:13

少なくともこの質問はやることやって躓いてると見受けられますし、回答をどう活かすかは質問者マターと考えています。
guest

0

関係演算の除算の問題です。IPAのデータベーススペシャリストの試験問題を調べてください。様々なSQLが書けるそうですが、紹介するのは not exists を2回使うやりかたです。

SQL

1select hotel_id from hotels a where not exists( 2 select 1 from tags c where c.tag in ('朝食付き','キャンセル無料') and not exists( 3 select 1 from hotels_tags b where c.tags_id = b.tags_id and b.hotel_id = a.hotel_id)); 4

投稿2019/02/28 13:22

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

sazi

2019/02/28 13:58 編集

シンプルですね。 条件としての変動要素が一つだけになるのでこちらの方が使い勝手は良いですね。
退会済みユーザー

退会済みユーザー

2019/02/28 18:44

おっしゃるとおり、はじめcount(*)=2を試しましたが、2も変動要素になることがわかり途中で除算に変更 しました。c.tag in ('朝食付き','キャンセル無料') といった選択条件をビューにして外に出せば教科書どおりになります。 それより、関係演算のひとつである除算の応用例が見つかったのが嬉しいですね。
sazi

2019/02/28 23:33

後は速度面ですね。 質問のデータ程度では違いは無さそうですけど、大量になるとどうかというところ。
退会済みユーザー

退会済みユーザー

2019/02/28 23:57

相関副問い合わせは遅いですから。除算の課題は効率化(他の方法の探求)です。
guest

0

結果としてどう見せたいのかによります。
命題を見る限りこうだと思います

SQL

1select * from hotels as t1 2inner join hotels_tags as t2 on t1.hotel_id = t2.hotel_id and t1.country_code = t2.country_code 3inner join tags as t3 on t2.tags_id = t3.tags_id 4where t1.hotel_id in( 5select hotel_id from hotels_tags as t4 6where exists (select 1 from tags where tag IN('朝食付き','キャンセル無料') and tags_id=t4.tags_id) 7group by hotel_id 8having count(distinct tags_id)=2 9)

しかしこれだと同じホテルが複数行に渡って表示されるので微妙
group_concat使ったほうがよいかも

SQL

1select 2t1.hotel_id 3,t1.country_code 4,t1.hotel_id 5,t1.hotel_name 6,t1.hotel_address 7,t1.hotel_tel 8,t1.price 9,t1.likes 10,group_concat(t3.tag) as tags 11from hotels as t1 12inner join hotels_tags as t2 on t1.hotel_id = t2.hotel_id and t1.country_code = t2.country_code 13inner join tags as t3 on t2.tags_id = t3.tags_id 14where t1.hotel_id in( 15select hotel_id from hotels_tags as t4 16where exists (select 1 from tags where tag IN('朝食付き','キャンセル無料') and tags_id=t4.tags_id) 17group by hotel_id 18having count(distinct tags_id)=2 19) 20group by hotel_id

投稿2019/02/28 12:27

yambejp

総合スコア114814

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

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

0

あんまりしっかり見てないので、ダメかもしれんが。
joinした結果のtagをor検索すれば、ヒットするのは、1件か2件なのでしょ?

で、having使って2件あるのが、望むホテルじゃないかな?

投稿2019/02/28 12:12

momon-ga

総合スコア4820

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問