繁体   English   中英

MySQL 多个条件分组依据/具有子句

[英]MySQL Multiple Conditions on Group By / Having Clause

我有三个表,它们都与以下结构相互关联。

模块类别表:

+------------------+----------------+------------+
| ModuleCategoryID | ModuleCategory | RequireAll |
+------------------+----------------+------------+
|               90 | Cat A          | YES        |
|               91 | Cat B          | NO         |
+------------------+----------------+------------+

模块类别技能表:

+------------------+---------+
| ModuleCategoryID | SkillID |
+------------------+---------+
|               90 |    1439 |
|               90 |    3016 |
|               91 |    1440 |
|               91 |    3016 |
+------------------+---------+

EmployeeSkill Table:
+---------+---------+
| EmpName | SkillID |
+---------+---------+
| Emp1    |    1439 |
| Emp1    |    3016 |
| Emp2    |    1440 |
| Emp2    |    3016 |
| Emp3    |    1439 |
| Emp4    |    3016 |
+---------+---------+

期望输出:

+------------------+-------+
| ModuleCategory   | Count |
+------------------+-------+
|            Cat A |     1 |
|            Cat B |     3 |
+------------------+-------+

我正在尝试按 ModuleCategoryID 分组并获取具有被跟踪技能的员工人数。

通常,我可以执行以下查询来获取数字:

select mc.ModuleCategory, Count(*) as Count from ModuleCategory as mc 
join ModuleCategorySkill as mcs on mc.ModuleCategoryID = mcs.ModuleCategoryID join EmployeeSkill as es on es.SkillID= mcs.SkillID 
group by mc.ModuleCategoryID

但是,我在 ModuleCategory 表中有一个 RequireAll 列,如果将其设置为“是”,则仅当员工拥有该类别中的所有技能时才应将其计为 1。 如果它设置为 NO 则它可以正常计算每一行并按它分组的行数增加计数。

我可以通过为每个 modulecategoryID 编写单独的查询并使用 Count( ) > 1(这将找到任何拥有 ModuleCategoryID 90 的所有技能的人)来实现这一点 如果有 3 个技能,我必须将其更改为具有计数( )> 2。如果没有人拥有指定的所有技能,则计数应为 0。

我需要一种能够做到这一点的动态方式,因为有大量数据并且为每个 ModuleCategoryID 编写一个查询并不是正确的方法。

另外,我正在使用 PHP,所以我可以循环并创建一个可以帮助我实现这一目标的 sql 字符串。 但是我知道我会在具有很多技能和模块类别 ID 的大表上遇到性能问题。

非常感谢有关如何实现这一目标的任何指导。

您可以通过加入总类别计数,然后使用条件聚合来实现:

select modulecategory, 
       count(case when requireall = 'yes'
               then if(s = t, 1, null)
               else s
             end) 
from (             
select modulecategory,empname, requireall, count(*) s, min(q.total) t
  from employeeskill e
    inner join modulecategoryskill mcs
      on e.skillid = mcs.skillid
    inner join modulecategory mc
      on mcs.modulecategoryid = mc.modulecategoryid
    inner join (
      select modulecategoryid, count(*) total
        from modulecategoryskill
        group by modulecategoryid
    ) q
    on mc.modulecategoryid = q.modulecategoryid
  group by modulecategory, empname
  ) qq
group by modulecategory;

演示在这里

这是在假设员工不会被分配两次相同的技能的情况下进行的,如果可能发生这种情况,则可以更改此查询以支持它,但这对我来说似乎是一个破碎的场景。

我们这里有一个内部查询,它整理了我们需要的所有信息(类别名称、员工姓名、是否需要所有技能、每个员工在该组中有多少技能以及该组中有多少技能),使用外部查询根据requireall的值,使用条件计数来更改行的计数requireall

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM