用于获取每个ID的表中条目总和的存储过程

时间:2013-05-07 18:27:54

标签: sql stored-procedures join sql-server-2008-r2

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

现在,我希望看到每个比例下的总人数-1和2以及3和4的特定技能名称1,技能名称2,...,技能名称。

这是我的表:

tblSkill:

ID | SkillName  

和另一个表格:

tblskillMetrics:

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

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

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

3 个答案:

答案 0 :(得分: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而是标识符delimited as required by Transact-SQL syntax。)

答案 1 :(得分: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

答案 2 :(得分: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