Mysql条件,用于对多对多表进行分组

时间:2014-06-16 14:24:33

标签: php mysql sql database

我想知道是否有人能想出更优雅的解决方案来解决我的问题。我很难找到类似的案例。

我有5张桌子。 3是员工,技能和单项技能的详细信息。其余2个是连接表。

skill_links

skill_id    subskill_id
1           4
1           5
2           4
2           6

emp_skill_links

employee_id    subskill_id    acquired
1              4              2013-04-05 00:00:00
1              5              2014-02-24 00:00:00
2              6              2012-02-26 00:00:00
2              5              2011-06-14 00:00:00    

两者都有多对多的关系。使用单项技能(skill_links)和具有单项技能的员工(emp_skill_links)的技能。

我想挑选已获得技能的所有单项技能的员工。我尝试用一​​个查询来完成它,但是无法通过涉及的分组来管理它。目前,我的解决方案是两个单独的查询,稍后在php数组中进行匹配。那就是:

SELECT sl.skill_id, COUNT(sl.subskill_id) as expected
FROM skill_links sl
GROUP BY sl.skill_id

与之比较:

SELECT sl.skill_id, esl.employee_id, COUNT(esl.subskill_id) as provided
FROM emp_skill_links esl
INNER JOIN skill_links sl
ON sl.subskill_id = esl.subskill_id
GROUP BY sl.skill_id, esl.employee_id   

我的问题是否有更有效的单一查询解决方案?或者不值得涉及的复杂性?

1 个答案:

答案 0 :(得分:0)

如果您认为包含子查询的查询满足您对“#34;更高效的单一查询解决方案”的要求,那么#34 (取决于你对"单个查询"的定义),那么这将有效。

SELECT employeeTable.employee_id
FROM
  (SELECT sl.skill_id, COUNT(*) AS subskill_count
  FROM skill_links sl
  GROUP BY sl.skill_id) skillTable
  JOIN
  (SELECT esl.employee_id, sl2.skill_id, COUNT(*) AS employee_subskills
   FROM emp_skill_links esl
     JOIN skill_links sl2 ON esl.subskill_id = sl2.subskill_id
   GROUP BY esl.employee_id, sl2.skill_id) employeeTable
  ON skillTable.skill_id = employeeTable.skill_id
 WHERE employeeTable.employee_subskills = skillTable.subskill_count

查询的作用:

  • 选择每项技能的子技能计数

  • 为每个主要技能选择每位员工的子技能计数

  • 根据主要技能加入这些结果

  • 从具有等于的子技能计数的员工中选择 主要技能的子技能计数

DEMO

在该示例中,用户1和3各自具有主要技能1的所有子技能。用户2仅具有主要技能2的3个子技能中的2个。

你会注意到这里的逻辑类似于你已经在做的事情,但它的优点是只有一个db请求(而不是两个)并且它不涉及PHP创建,循环,比较和减少数组的工作。