COUNT 和 MAX/MIN 和(HAVING?)在一个查询/ AdventureWorks2017 任务中
COUNT and MAX/MIN and (HAVING?) in one query/ AdventureWorks2017 task
我在 AdventureWorks2017 DB 中有一个训练任务。任务如下:
我需要一份职位列表,其中女性工作的比例最少和最多。只考虑至少有 4 人工作的那些。
到目前为止,我的代码如下所示:
select a.JobTitle, AVG(ertek) as avg_women, COUNT(*) as sum_women
from
(select BusinessEntityID, JobTitle, Gender, CASE WHEN Gender = 'F' THEN 1.0 ELSE 0.0
END as ertek
from HumanResources.Employee) a
group by a.JobTitle
这会返回所有的职位名称、这些职位中女性的平均数以及职位中女性的总和。问题是我不能在查询中使用 MAX 和 MIN(也许我需要创建另一个子查询?)。我需要完成任务的最后一部分“只考虑至少有 4 人工作的那些”。
感谢您的帮助!
ER图:https://homel.vsb.cz/~dan11/ddj/AdventureWorks2008_db_diagram.pdf
一次满足这些需求,逐步构建您的解决方案。
运行您的查询在每增加一步后确认预期的结果!
步骤
- 仅限 4 人以上的职位:
group by e.JobTitle having count(1) >= 4
- 按比例计算女性人数(我将其解释为“一个职位中女性的相对人数”)。这需要总计,女性只计:
count(1) as JobTitleCount
和
count(case when e.Gender = 'F' then 1 end) as FemaleCount
相对(比例)数或百分比则变为:
count(case when e.Gender = 'F' then 1 end)*100.0/count(1) as FemalePercentage
- “最少”和“最多”表示 ranking functions 带有
order by
子句:
dense_rank() over(order by
<此处显示第 2 步的百分比> ) as RankLeast
和
dense_rank() over(order by
<此处显示第 2 步的百分比> desc) as RankMost
- 过滤任一排名第一的职位:
where jfpr.RankLeast = 1 or jfpr.RankMost = 1
中间结果
步骤 1. 到 3.
select e.JobTitle,
count(1) as JobTitleCount,
count(case when e.Gender = 'F' then 1 end) as FemaleCount,
count(case when e.Gender = 'F' then 1 end)*100.0/count(1) as FemalePercentage,
dense_rank() over(order by count(case when e.Gender = 'F' then 1 end)*100.0/count(1) ) as FemalePercentageRankLeast,
dense_rank() over(order by count(case when e.Gender = 'F' then 1 end)*100.0/count(1) desc) as FemalePercentageRankMost
from HumanResources.Employee e
group by e.JobTitle
having count(1) >= 4
order by FemalePercentage;
完整解决方案
将整个先前的查询移动到子查询 jfpr
中,并省略最终结果不再需要的列(JobTitleCount
和 FemaleCount
)。 order by
移到子查询之外。
select jfpr.JobTitle,
jfpr.FemalePercentage
from ( select e.JobTitle,
count(case when e.Gender = 'F' then 1 end)*100.0/count(1) as FemalePercentage,
dense_rank() over(order by count(case when e.Gender = 'F' then 1 end)*100.0/count(1) ) as FemalePercentageRankLeast,
dense_rank() over(order by count(case when e.Gender = 'F' then 1 end)*100.0/count(1) desc) as FemalePercentageRankMost
from HumanResources.Employee e
group by e.JobTitle
having count(1) >= 4 ) jfpr -- job female percentage rank
where jfpr.FemalePercentageRankLeast = 1
or jfpr.FemalePercentageRankMost = 1
order by jfpr.FemalePercentage;
结果
在我的 AdventureWorks 副本上(不知道我现在有什么版本)这会产生:
JobTitle FemalePercentage
---------------------------- ----------------
Quality Assurance Technician 0.000000000000
Scheduling Assistant 0.000000000000
Janitor 50.000000000000
Application Specialist 50.000000000000
我在 AdventureWorks2017 DB 中有一个训练任务。任务如下: 我需要一份职位列表,其中女性工作的比例最少和最多。只考虑至少有 4 人工作的那些。
到目前为止,我的代码如下所示:
select a.JobTitle, AVG(ertek) as avg_women, COUNT(*) as sum_women
from
(select BusinessEntityID, JobTitle, Gender, CASE WHEN Gender = 'F' THEN 1.0 ELSE 0.0
END as ertek
from HumanResources.Employee) a
group by a.JobTitle
这会返回所有的职位名称、这些职位中女性的平均数以及职位中女性的总和。问题是我不能在查询中使用 MAX 和 MIN(也许我需要创建另一个子查询?)。我需要完成任务的最后一部分“只考虑至少有 4 人工作的那些”。 感谢您的帮助!
ER图:https://homel.vsb.cz/~dan11/ddj/AdventureWorks2008_db_diagram.pdf
一次满足这些需求,逐步构建您的解决方案。
运行您的查询在每增加一步后确认预期的结果!
步骤
- 仅限 4 人以上的职位:
group by e.JobTitle having count(1) >= 4
- 按比例计算女性人数(我将其解释为“一个职位中女性的相对人数”)。这需要总计,女性只计:
count(1) as JobTitleCount
和
count(case when e.Gender = 'F' then 1 end) as FemaleCount
相对(比例)数或百分比则变为:
count(case when e.Gender = 'F' then 1 end)*100.0/count(1) as FemalePercentage
- “最少”和“最多”表示 ranking functions 带有
order by
子句:
dense_rank() over(order by
<此处显示第 2 步的百分比>) as RankLeast
和
dense_rank() over(order by
<此处显示第 2 步的百分比>desc) as RankMost
- 过滤任一排名第一的职位:
where jfpr.RankLeast = 1 or jfpr.RankMost = 1
中间结果
步骤 1. 到 3.
select e.JobTitle,
count(1) as JobTitleCount,
count(case when e.Gender = 'F' then 1 end) as FemaleCount,
count(case when e.Gender = 'F' then 1 end)*100.0/count(1) as FemalePercentage,
dense_rank() over(order by count(case when e.Gender = 'F' then 1 end)*100.0/count(1) ) as FemalePercentageRankLeast,
dense_rank() over(order by count(case when e.Gender = 'F' then 1 end)*100.0/count(1) desc) as FemalePercentageRankMost
from HumanResources.Employee e
group by e.JobTitle
having count(1) >= 4
order by FemalePercentage;
完整解决方案
将整个先前的查询移动到子查询 jfpr
中,并省略最终结果不再需要的列(JobTitleCount
和 FemaleCount
)。 order by
移到子查询之外。
select jfpr.JobTitle,
jfpr.FemalePercentage
from ( select e.JobTitle,
count(case when e.Gender = 'F' then 1 end)*100.0/count(1) as FemalePercentage,
dense_rank() over(order by count(case when e.Gender = 'F' then 1 end)*100.0/count(1) ) as FemalePercentageRankLeast,
dense_rank() over(order by count(case when e.Gender = 'F' then 1 end)*100.0/count(1) desc) as FemalePercentageRankMost
from HumanResources.Employee e
group by e.JobTitle
having count(1) >= 4 ) jfpr -- job female percentage rank
where jfpr.FemalePercentageRankLeast = 1
or jfpr.FemalePercentageRankMost = 1
order by jfpr.FemalePercentage;
结果
在我的 AdventureWorks 副本上(不知道我现在有什么版本)这会产生:
JobTitle FemalePercentage
---------------------------- ----------------
Quality Assurance Technician 0.000000000000
Scheduling Assistant 0.000000000000
Janitor 50.000000000000
Application Specialist 50.000000000000