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

Sql 用于获取表中每个ID的条目的总和的存储过程,sql,stored-procedures,join,sql-server-2008-r2,Sql,Stored Procedures,Join,Sql Server 2008 R2,我正在编写一个存储过程,其中有一个名为scale的列,用于存储单选按钮的结果,对于每种类型的技能名称,该单选按钮被选择为1/2/3/4 现在,我想看看每个等级下的总人数——1和2,3和4,对于特定的技能名称1,技能名称2,…,技能名称20 这是我的桌子: tblSkill: ID | SkillName 另一个表格如下: tblskillMetrics: ID | SkillID | EmployeeID | Scale 下面是我试图写的查询: Create Procedure spGe

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

现在,我想看看每个等级下的总人数——1和2,3和4,对于特定的技能名称1,技能名称2,…,技能名称20

这是我的桌子:

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
通过使用这个存储过程,我可以得到我想要的结果格式,但在每个输出中:不适用、初学者、熟练者或专家是相同的,它是表中所有条目的总和


请有人告诉我哪里出了问题。

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

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

从逻辑上讲,您是根据两个标准进行分组的,即规模和技能名称。然而,如果我理解正确的话,每一行应该代表一个技能名称。因此,您应该仅按
tblSkill.Name
进行分组。要在单独的列中获得不同比例的不同计数,可以使用条件聚合,即对(通常)涉及
大小写
构造的表达式进行聚合。以下是您可以采取的措施:

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
;
注意,这种查询有一种特殊的语法。它使用关键字,因为您得到的基本上是一个分组结果集,以分组标准之一为中心,在本例中为scale。这就是如何通过
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,而是标识符。)

您可以使用类似以下内容:

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 

谢谢@Andriy M,这帮了大忙。我也试过类似的方法,但在某个地方犯了一些错误,所以没有达到效果。谢谢你也向我解释了整件事。谢谢@Dan Bracuk的帮助。