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

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

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

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

Q&A

解決済

3回答

2864閲覧

【SQL文の書き方について】複数キーワードと複数キーワードを除外した検索

ssk

総合スコア332

SQL

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

0グッド

1クリップ

投稿2017/08/22 03:34

編集2017/08/22 06:31

###前提・実現したいこと
リレーショナルデータベースを想定しています。
以下のキーワードからSQL文を作成するには、どのような書き方がありますか?
※全てのカラムが検索対象

複数キーワード:「東京 派遣」
除外キーワード:「時給 歩合」

###補足情報(言語/FW/ツール等のバージョンなど)
参考書やこちらを参考にSQL文を考えているのですが
カラム全体を対象にしたいので、イメージができません。

サブクエリで除外キーワードを検索してから
さらにキーワード検索する方法が良いと思っています。
(正解かわかりませんが、、、)

何卒、助言の程よろしくお願いいたします。

###追記
テーブル構成は以下の通りです。

masterテーブル

idnamepre_idem_id
1会社名111
2会社名213
3会社名321

master_formテーブル

idform_id
12
21
22
31
33

formテーブル

form_idname
1正社員
2派遣
3アルバイト

emテーブル

idname
1固定給
2時給
3歩合

preテーブル

idname
1東京
2大阪
3名古屋

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2017/08/22 03:46

テーブルの構造、キーワードを検索する対象のカラムの実例なども教えて下さい。
SVC34

2017/08/22 03:54 編集

「東京」と「渋谷区」が含まれているレコード⇒除外する で合っていますか
hihijiji

2017/08/22 04:05

> ※全てのカラムが検索対象 テーブル設計が上手くない可能性が高いです。適切な正規化を行えば検索条件と対象カラムは絞られてきます。
A.Ichi

2017/08/22 04:17

全てのカラム?であればテーブルの項目は全てcharで構成されている事になりますが・・・
ssk

2017/08/22 04:54

検索/除外キーワードの変更とテーブル構成について追記・修正いたしました。また、全てのカラムではなく、idなどの数字を除いたカラムです。言葉足らずで申し訳ございません。
tsuemura

2017/08/22 06:08

現在、検索に使用しているSQLを追記してもらえますか?
guest

回答3

0

master_formの使い所がイマイチわかりません
masterにあるform_idと整合性がとれていないのでは?

追記

formはmaster_form経由でmasterとつながるのですね
idやnameなどかぶっているものが多いのでちょっと整理して以下例示します

SQL

1create table master(m_id int,name varchar(20),p_id int,e_id int); 2insert into master values(1,'会社名1',1,1),(2,'会社名2',1,3),(3,'会社名3',2,1); 3 4create table master_form(m_id int,f_id int); 5insert into master_form values(1,2),(2,1),(2,2),(3,1),(3,3); 6 7create table form(f_id int,f_name varchar(20)); 8insert into form values(1,'正社員'),(2,'派遣'),(3,'アルバイト'); 9 10create table em(e_id int,e_name varchar(20)); 11insert into em values(1,'固定給'),(2,'時給'),(3,'歩合'); 12 13create table pre(p_id int,p_name varchar(20)); 14insert into pre values(1,'東京'),(2,'大阪'),(3,'名古屋');

こうであれば、検索は以下になります

SQL

1select * from master as m 2inner join master_form as mf on m.m_id=mf.m_id 3inner join form as f on mf.f_id=f.f_id 4inner join em as e on m.e_id=e.e_id 5inner join pre as p on m.p_id=p.p_id 6

このデータから複数キーワード:「東京 派遣」、除外キーワード:「時給 歩合」 を
当てはめると結果はどれをほしいのでしょうか?
m_id単位で集計したいのでしょうか?

調整

インデックスの付け直しおよびexistsをつかってこれでどうでしょう?

SQL

1create table master(m_id int,name varchar(20),p_id int,e_id int,index(m_id,p_id,e_id)); 2insert into master values(1,'会社名1',1,1),(2,'会社名2',1,3),(3,'会社名3',2,1); 3 4create table master_form(m_id int,f_id int,index(m_id,f_id)); 5insert into master_form values(1,2),(2,1),(2,2),(3,1),(3,3); 6 7create table form(f_id int,f_name varchar(20),index(f_id,f_name)); 8insert into form values(1,'正社員'),(2,'派遣'),(3,'アルバイト'); 9 10create table em(e_id int,e_name varchar(20),index(e_id,e_name)); 11insert into em values(1,'固定給'),(2,'時給'),(3,'歩合'); 12 13create table pre(p_id int,p_name varchar(20),index(p_id,p_name)); 14insert into pre values(1,'東京'),(2,'大阪'),(3,'名古屋'); 15

SQL

1select * from master as m 2where 1 3and exists(select m_id from master_form as mf inner join form as f on mf.f_id=f.f_id and f.f_name='派遣' where mf.m_id=m.m_id) 4and exists(select e_id from em as e where not e.e_name='時給' and not e_name='歩合' and e.e_id=m.e_id) 5and exists(select p_id from pre as p where p.p_name='東京' and p.p_id=m.p_id) 6

投稿2017/08/22 06:28

編集2017/08/22 07:34
yambejp

総合スコア114583

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

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

ssk

2017/08/22 06:31

ご指摘ありがごうざいます。 おっしゃる通りでしたので、テーブルを修正いたしました。
ssk

2017/08/22 06:57

ありがとうございます。 m_id単位で集計したいです。
yambejp

2017/08/22 07:34

調整版を追記しておきました
ssk

2017/08/24 04:26

返信が遅くなってしまい、ありがとうございます。 existsを利用する方向で進めていきたいと思います。
guest

0

ベストアンサー

mysqlで作成してみました。

sql

1select t1.`name`, t3.`name`, t4.`name`, t5.`name` 2from master t1 3join master_form t2 on t1.form_id=t2.id 4join form t3 on t2.form_id=t3.form_id 5join em t4 on t1.em_id=t4.id 6join pre t5 on t1.pre_id=t5.id 7where t5.`name`='東京' 8and t3.`name`='派遣' 9and t4.`name` not in ('時給','歩合') 10;

ERが不明な部分が有り想像して作成しました。
追加

sql

1select t1.`name`, t3.`name`, t4.`name`, t5.`name` 2from master t1 3join master_form t2 on t1.form_id=t2.id 4join form t3 on t2.form_id=t3.form_id and t3.name='派遣' 5join em t4 on t1.em_id=t4.id and t4.`name` not in ('時給','歩合') 6join pre t5 on t1.pre_id=t5.id and t5.`name`='東京' 7;

投稿2017/08/22 05:57

編集2017/08/22 06:07
A.Ichi

総合スコア4070

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

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

ssk

2017/08/22 06:01

SQL文まで、ありがとうございます! サブクエリではなく、テーブル結合した後にwhereとnot inを同時に行う方法ですとウエイトが10秒ほどあります。これはしょうがない、、、ということでしょうか?
A.Ichi

2017/08/22 06:04

もしデータ量が大量であればwhereでの絞りでは、時間が掛かります。分かり易さを優先してみました。ONにて絞れば高速化が可能です。
ssk

2017/08/22 06:09

おっしゃる通り、データ量が3万ほどあります。 ONで絞るというと、A.Ichi様が提示してくださったSQL文の場合 どのようになりますか? http://d.hatena.ne.jp/r_ikeda/20090610/outerjoin ↑こちらのサイトを見るかぎり、テーブル結合時にONを使うのでしょうか?
ssk

2017/08/22 06:11

早速、ありがとうございます!><
ssk

2017/08/22 06:12

サブクエリではなく、joinのタイミングで省いてしまう方法もあるのですね。
guest

0

フリーワード検索的なものをやろうとしているのでしょうか。

全カラムを結合して、LIKEまたはNOT LIKEで検索するくらいしか思いつきません。
以下はPostgreSQLの場合です。

SELECT * FROM table1 WHERE col1 || col2 || col3 || ... || col99 LIKE ('%東京%','%大阪%', '%時給%') AND col1 || col2 || col3 || ... || col99 NOT LIKE ('%渋谷区%', '%目黒区%', '%正社員%');

各DBMSごとの文字列結合の方法はhttp://www.sql-reference.com/string/concatenate.htmlを、
ワイルドカード検索はhttp://www.sql-reference.com/select/like.htmlを参考にしてください。

ただ、恐らくパフォーマンス上の問題があると思います。
正規化や全文検索インデックスなど、必要に応じて検討してください。

投稿2017/08/22 04:22

tsuemura

総合スコア663

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

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

ssk

2017/08/22 05:06

ありがとうございます。 >>>ただ、恐らくパフォーマンス上の問題があると思います。 複数テーブルのため、結合してからLIKEとNOT LIKEをやってみたんですが ウエイトが10秒程ありまして。。正規化はできているのでサブクエリを絡ませて。と考えていました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問