2016-07-18 8 views
1

私は構造 "id、user_id、skill"を持つ "one to many"テーブルを持っています。ユーザーは複数のスキルを持つことができます(例: "mysql"と "php")。Mysql - "one to many"テーブルで検索する

誰かがスキル "php"でユーザーを検索したい場合、 "mysql"は検索フォーム "php mysql"で記述する必要があります。

MYSQLクエリ(条件)を"... WHERE skill LIKE '%php%' AND skill LIKE '%mysql%'"としましたが、何も返しません。

どうすれば改善できますか?

また、私は"WHERE CONCAT_WS(' ', skill) LIKE '%php%' AND CONCAT_WS(' ', skill) LIKE '%mysql%'"のようなものを試しました。それも何も戻っていない。

ありがとうございました!

答えて

1

使用条件の集約:

SELECT t1.id, t1.name 
FROM users t1 
INNER JOIN 
(
    SELECT s.user_id 
    FROM skills s 
    GROUP BY s.user_id 
    HAVING SUM(CASE WHEN s.skill LIKE '%php%' OR 
         s.skill LIKE '%mysql%' THEN 1 ELSE 0 END) >= 2 
) t2 
    ON t2.user_id = t1.id 

内側のクエリは、両方のPHPMySQLスキルを持っているユーザーを見つけ、この結果は、この要件に一致する名前だけを返すようにusersテーブルをフィルタリングするために使用されます。

特定のスキルが特定のユーザーに対して1回だけ表示されると私は考えています。同じスキルが同じユーザーに対して複数回表示される可能性がある場合は、クエリをわずかに変更する必要があります。

SQLFiddle

更新:

あなたskills表は、特定のユーザーに複数回のためにリストされている同じスキルを持っている可能性がある場合は、DISTINCTを使用して、これらの重複エントリを無視することができます

SELECT t1.id, t1.name 
FROM users t1 
INNER JOIN 
(
    SELECT s.user_id 
    FROM (SELECT DISTINCT user_id, skill FROM skills) s 
    GROUP BY s.user_id 
    HAVING SUM(CASE WHEN s.skill LIKE '%php%' OR s.skill LIKE '%mysql%' 
       OR s.skill LIKE '%javascript%' THEN 1 ELSE 0 END) >= 3 
) t2 
    ON t2.user_id = t1.id 

マークの下のフィドルでは、ではなく、が結果セットに表示されます。彼はスキルとしてPHPを2回掲載していますが、MySQLまたはJavaScriptを持っていません。

SQLFiddle

+0

また、何も返さないです。ここで見てください、私はSQLスキーマを作ったばかりです。http://sqlfiddle.com/#!9/5008a6/1 – Ridd

+1

@Riddあなたは 'AND'演算子ではなく' OR'演算子を使いたいと思います。私の更新を確認してください。 –

+0

これは素晴らしいことです!ありがとうございました。それはより複雑ですが、私はそれも効率的で、私のdbを殺さないことを願っ:)再びありがとう。 – Ridd

0

例えば、A REGEXPは、より効率的かもしれませんが、あなたはそれを確認するためにベンチマークする必要があると思います

SELECT * from table where field REGEXP 'php|mysql'; 

For Ref.

+0

これはPHPやMySQLの儀式を与えるでしょうか? phpとmysqlが必要です –

+0

これは '%keyword%'のように動作します。 例:私はユーザーテーブルを持つdbを持っています。私は電子メールIDに基づいて検索したいと思います。 ユーザー*からのSELECT *ユーザー名REGEXP 'bhavin | kenny'; しかし、私は "bhavin @ tech"と "kenny @ tech"の列に値を持っています –

+0

これはORステートメントであり、ANDステートメントではありませんか? –