2

我正在编写一个存储过程,其中有一个名为 scale 的列,该列存储来自为每种技能名称选择为 1/ 2/ 3/ 4 的单选按钮的结果。

现在,我想查看特定技能名称 1、技能名称 2、...、技能名称 20 的每个等级 - 1 和 2 以及 3 和 4 下的总人数。

这是我的桌子:

tbl技能:

ID | SkillName  

和另一个表:

tblskill指标:

ID | SkillID | EmployeeID | Scale

这是我试图写的查询:

Create Procedure spGetSkillMetricsCount
As
Begin
   SELECT 
      tblSkill.Name as skillname,
      (select COUNT(EmployeeID) from tblSkillMetrics where tblSkillMetrics.Scale=1) AS NotAplicable,
      (select COUNT(EmployeeID) from tblSkillMetrics where tblSkillMetrics.Scale=2 ) AS Beginner,
      (select COUNT(EmployeeID) from tblSkillMetrics where tblSkillMetrics.Scale=3 ) AS Proficient,
      (select COUNT(EmployeeID) from tblSkillMetrics where tblSkillMetrics.Scale=4 ) AS Expert
   FROM
      tblSkill
   INNER JOIN 
      tblSkillMetrics ON tblSkillMetrics.SkillID = tblSkill.ID
   GROUP BY 
      tblSkillMetrics.Scale, tblSkill.Name 
   ORDER BY 
      skillname DESC
END

通过使用这个存储过程,我能够获得我想要的结果格式,但在每个输出中:不适用、初学者、精通或专家是相同的,它是表中所有条目的总和。

请有人建议我哪里出错了。

4

3 回答 3

2

从逻辑上讲,您按两个标准进行分组,即规模和技能名称。但是,如果我理解正确,每一行都应该代表一个技能名称。因此,您应该tblSkill.Name只分组。要在不同的列中获得不同比例的不同计数,您可以使用条件聚合,即(通常)涉及CASE构造的表达式上的聚合。您可以这样做:

SELECT 
   tblSkill.Name AS skillname,
   COUNT(CASE tblSkillMetrics.Scale WHEN 1 THEN EmployeeID END) AS NotAplicable,
   COUNT(CASE tblSkillMetrics.Scale WHEN 2 THEN EmployeeID END) AS Beginner,
   COUNT(CASE tblSkillMetrics.Scale WHEN 3 THEN EmployeeID END) AS Proficient,
   COUNT(CASE tblSkillMetrics.Scale WHEN 4 THEN EmployeeID END) AS Expert
FROM
   tblSkill
INNER JOIN 
   tblSkillMetrics ON tblSkillMetrics.SkillID = tblSkill.ID
GROUP BY 
   tblSkill.Name 
ORDER BY 
   skillname DESC
;

请注意,这种查询有一种特殊的语法。它使用PIVOT关键字,因为您得到的本质上是一个分组结果集,该结果集以分组标准之一为中心,在这种情况下是缩放。这就是可以通过以下方式实现相同的方法PIVOT

SELECT
   skillname,
   [1] AS NotAplicable,
   [2] AS Beginner,
   [3] AS Proficient,
   [4] AS Expert
FROM (
   SELECT 
      tblSkill.Name AS skillname,
      tblSkillMetrics.Scale,
      EmployeeID
   FROM
      tblSkill
   INNER JOIN 
      tblSkillMetrics ON tblSkillMetrics.SkillID = tblSkill.ID
) s
PIVOT (
   COUNT(EmployeeID) FOR Scale IN ([1], [2], [3], [4])
) p
;

基本上,PIVOT意味着分组。源数据集中除一个之外的所有列都是分组标准,即在 PIVOT 子句中未用作聚合函数参数的每一列都是分组标准。其中之一也被指定为以结果为中心的那个。(同样,在这种情况下,它是规模。)

因为分组是隐式的,所以使用派生表来避免按不必要的标准进行分组。的值Scale成为 PIVOT 子句生成的新列的名称。(这就是为什么它们在 PIVOT 中列出时用方括号分隔:它们不是该上下文中的 ID,而是按 Transact-SQL 语法要求分隔的标识符。)

于 2013-05-07T19:42:20.967 回答
1

一个案例构造而不是所有这些子查询可能会起作用。

select tblSkill.name skillname
, case when tblSkillMetrics = 1 then 'Not Applicable'
etc
else 'Expert' end level
, count(employeeid) records
from tblSkill join tblSkillMetrics 
on tblSkillMetrics.SkillID = tblSkill.ID
group by tblSkill.name
, case when tblSkillMetrics = 1 then 'Not Applicable'
etc
else 'Expert' end level
order by skillname desc
于 2013-05-07T18:49:05.497 回答
0

你可以使用这样的东西:

SELECT sum(case when tblskillmetrics.scale = 2 then 1 else 0 end) Beginner,  
       sum(case when tblskillmetrics.Scale=3 then 1 else 0 end)Proficient, 
       SUM(case when tblSkillMetrics.Scale=4 then 1 else 0 end)Expert,
       tblSkillGroup.ID AS GroupID,tblSkillGroup.Name AS GroupName,
       tblSkill.ID AS SkillID 
       , tblSkill.Name AS SkillName

FROM  tblSkill INNER JOIN tblSkillMetrics 
         ON tblSkillMetrics.SkillID=tblSkill.ID 
ORDER BY GroupName DESC 
于 2013-05-21T14:04:14.267 回答