2017-03-28 28 views
1

私は多対多選択クエリを作成しようとしています。MySQL多対多選択

  • プロファイル
  • スキル
  • Profile_skills(プロファイルIDとスキルID)私は、すべてのスキル(例えばPHP)とを検索できるようにしたい

:私は3つのテーブルを持っていますそのスキルを持つプロフィールは一覧に表示されますが、その他のスキルもすべて含まれています。ほとんどのフリーランスサイトと同様に、私は彼らがMySQLなどを知っていることも知ることができます。

が正しいとわかりましたすべてのスキルを含むプロファイルに関するすべての情報を得る方法。これまでのところ私の最高の結果です:

SELECT * FROM profiles INNER JOIN profile_skills ON 
profile_skills.profil_id = profiles.profil_id INNER JOIN skills ON 
skills.skill_id = profile_skills.skill_id WHERE skill = 'PHP' 

しかし、これは1つのスキルで、残りの部分ではなく、私にプロファイルを与えます。

結果: http://imgur.com/E9PEiaU

予想:ユーザーID 1は、そのスキルを持っている場合 は、例えば、 "C#の" のために、ID、スキル "PHP"、およびスキルの残りの部分を持っているために。 http://imgur.com/5bCG4qo

私がスキルを持つプロファイルを検索すると、そのようにプロファイルの残りの部分がスキルを取得して表示されます。

+2

なぜgroup by ??? – scaisEdge

+1

GROUP BYとSELECT *を行うことはできませんが、私はエラーが出なかったことに驚いています。 – Forbs

+0

あなたはskill = 'PHP'なので、このスキルに関連するデータだけを取得します。 – scaisEdge

答えて

0

サブクエリでアカウントを特定し、スーパークエリで詳細を読み込むことができます(必要な場合はスキルGROUP_CONCAT)。ような何か:

SELECT profiles.*, GROUP_CONCAT(skills.skill SEPARATOR ', ') AS the_skillz 
FROM profiles INNER JOIN profile_skills (...) INNER JOIN skills (...) 
WHERE profiles.profile_id IN (
    SELECT DISTINCT profile_id 
    FROM profile_skills INNER JOIN skills (...) 
    WHERE skills.skill = 'PHP' 
) 
GROUP BY profiles.profile_id; 
+0

私はこれを試しましたが、これは2つの結果、各スキルを1つ返します。彼のプロフィールと同じラインで両方のスキルを返す方法はありませんか?だから私は、スキルを持っているので何回も返されたIDのプロフィールを取得していないのですか? –

+0

グループconcat(私は編集された答え)を使うことができます - これはmysql構文ですが、ほとんどのdbエンジンは似ています。パフォーマンス上の理由から、私は1つのクエリでこれをすべて行うつもりはありません。 1つのクエリを実行して、一致するプロファイルIDを取得し、データを個別に読み込むロード/表示ロジックを表示します。 – redreinard

0

は、あなたが望む結果を得るためにprofile_skillsskillsテーブルを再参加することができます。

| p.id | p.name | s.id |  s.skill  | 
--------------------------------------------- 
| 1 | rasmus | 1 |   PHP  | 
| 1 | rasmus | 2 |  Linux  | 
| 2 | thomas | 1 |   PHP  | 
| 2 | thomas | 3 | Eating Sandwiches | 

は、スキルのリストを1行の各プロファイルを取得するためのさまざまな方法があります。

SELECT p.*, s2.* 
FROM skills s1 
INNER JOIN profile_skills ps1 ON s.skill_id = ps1.skill_id 
INNER JOIN profiles p ON ps1.profil_id = p.profil_id 
INNER JOIN profile_skills ps2 ON p.profil_id = ps2.profil_id 
INNER JOIN skills s2 ON ps2.skill_id = s2.skill_id 
WHERE s1.skill = 'PHP' 

これはあなたにこのような結果を得ることができます。 1つの方法はMySQLでGROUP_CONCATです。

SELECT p.profil_id, p.profile_name, GROUP_CONCAT(s2.skill) AS skills 
FROM skills s1 
INNER JOIN profile_skills ps1 ON s.skill_id = ps1.skill_id 
INNER JOIN profiles p ON ps1.profil_id = p.profil_id 
INNER JOIN profile_skills ps2 ON p.profil_id = ps2.profil_id 
INNER JOIN skills s2 ON ps2.skill_id = s2.skill_id 
WHERE s1.skill = 'PHP' 
GROUP BY p.profil_id 

私はあなたの列が実際にあるかわからない、とあなたは他のものを追加、あるいはまだp.*を使用することができるので、例えば​​列を追加しました。技術的にはprofileの他の列はGROUP BY p.profil_idで定義されておらず、一般的にはグループ化や集約関数に含まれていない列は選択しないでください。の場合はこれは、すべて同じ行の同じ値を持つため、同じp.profil_idです。

もう一つの方法は、単に最初のクエリを使用してPHPでグループ化を行うことです。

$previous_id = null; 
while ($row = some_fetch_method()) { 
    if ($row['profil_id'] != $previous_id) { 
     echo "<h3>$row[profile_name]</h3>"; 
    } 
    echo "<div>$row[skill]</div>"; 
} 

明らかHTMLは非常にあなたが必要なもの、一般的な考え方を示すために十分であるべきではありません。