我正在尝试创建一个 MySQL 多对多选择查询。我有三个表:
- 简介
- 技能
- Profile_skills(个人资料 ID 和技能 ID)
我希望能够搜索一项技能(例如 PHP),并且所有具有该技能的个人资料都会显示在列表中,但包括他们所有其他技能。像大多数自由网站一样,所以我也可以看到他们知道 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'
但这只为我提供了一项技能的概况,而不是其他技能。
预期: 要拥有 ID、技能“PHP”和其他技能,例如“C#”(如果用户 ID 1 拥有该技能)。 http://imgur.com/5bCG4qo
就像这样,当我搜索具有技能的个人资料时,它还会显示该个人资料的其余部分获得的技能。
最佳答案
您可以重新加入profile_skills
和skills
表以获得您想要的结果。
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'
这会得到这样的结果:
| 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 |
有多种不同的方法可以将每个配置文件与技能列表排成一行。一种方法是在 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
例如,我添加了 profile_name
列,因为我不知道您的列实际上是什么,您可以添加其他列,甚至仍然使用 p.*
。从技术上讲,profile
中的其他列未使用 GROUP BY p.profil_id
定义,您通常不应选择既未包含在分组中也未包含在分组中的列一些聚合函数,但 MySQL 在这种情况下会为您处理,因为对于具有相同 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 不能完全满足您的需要,但它应该足以展示总体思路。
关于php - MySQL多对多选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43077641/