MySQL Group By / Having 子句的多个条件
MySQL Multiple Conditions on Group By / Having Clause
我有三个 table 都与以下结构相互关联。
模块类别Table:
+------------------+----------------+------------+
| ModuleCategoryID | ModuleCategory | RequireAll |
+------------------+----------------+------------+
| 90 | Cat A | YES |
| 91 | Cat B | NO |
+------------------+----------------+------------+
ModuleCategorySkill Table:
+------------------+---------+
| 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 table 中有一列 RequireAll,如果将其设置为 'YES',只有当员工具备该类别中的所有技能时,才应将其计为 1。如果将其设置为 NO 则它可以正常计算每一行并将计数增加它分组所依据的行数。
我可以通过为每个 modulecategoryID 编写单独的查询并使用具有 Count() > 1 的查询来实现这一点(这将找到任何拥有 ModuleCategoryID 90 的所有技能的人)。如果有 3 种技能,我必须将其更改为 Having Count() > 2。如果没有人拥有指定的所有技能,则计数应为 0。
我需要一种能够执行此操作的动态方法,因为有大量数据并且为每个 ModuleCategoryID 编写一个查询不是正确的方法。
此外,我正在使用 PHP,因此我可以遍历并创建一个 sql 字符串来帮助我实现此目的。但我知道我会 运行 进入具有大量技能和模块类别 ID 的大型 table 的性能问题。
非常感谢任何关于如何实现这一目标的指导。
您可以通过加入总类别计数,然后使用条件聚合来实现:
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
.
的值更改行的统计方式
我有三个 table 都与以下结构相互关联。
模块类别Table:
+------------------+----------------+------------+
| ModuleCategoryID | ModuleCategory | RequireAll |
+------------------+----------------+------------+
| 90 | Cat A | YES |
| 91 | Cat B | NO |
+------------------+----------------+------------+
ModuleCategorySkill Table:
+------------------+---------+
| 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 table 中有一列 RequireAll,如果将其设置为 'YES',只有当员工具备该类别中的所有技能时,才应将其计为 1。如果将其设置为 NO 则它可以正常计算每一行并将计数增加它分组所依据的行数。
我可以通过为每个 modulecategoryID 编写单独的查询并使用具有 Count() > 1 的查询来实现这一点(这将找到任何拥有 ModuleCategoryID 90 的所有技能的人)。如果有 3 种技能,我必须将其更改为 Having Count() > 2。如果没有人拥有指定的所有技能,则计数应为 0。
我需要一种能够执行此操作的动态方法,因为有大量数据并且为每个 ModuleCategoryID 编写一个查询不是正确的方法。
此外,我正在使用 PHP,因此我可以遍历并创建一个 sql 字符串来帮助我实现此目的。但我知道我会 运行 进入具有大量技能和模块类别 ID 的大型 table 的性能问题。
非常感谢任何关于如何实现这一目标的指导。
您可以通过加入总类别计数,然后使用条件聚合来实现:
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
.