存储过程在SELECT子句中显示不同的COUNT

时间:2011-12-14 12:07:07

标签: asp.net .net sql sql-server stored-procedures

我已经花了好几个小时才想出办法,但我还没有找到合适的解决方案。

我在SQL Server中有一个名为EmailTasks的表:

 Id  | HasFailed | CreateDate
 19  |   1       |  10/11/2011
 29  |   0       |  09/11/2011
 15  |   1       |  14/12/2011

我想构建一个接受两个参数的商店过程:@beginDate@endDate

它从表EmailTasks中选择相关记录(即CreateDate@beginDate之间的@endDate)并返回包含3列的下表:

  1. TotalEmails:电子邮件总数
  2. Failed:失败的电子邮件数量(hasFailed = 1),
  3. Suceess:成功的电子邮件数量(hasFailed = 0)。
  4. 例如:sp_GetEmailTemplateStatistics('08/11/2011', '11/11/2011')将返回:

    TotalEmails | Failed | Suceess
         2      |  1     |  1  
    

    请注意:由于Id=15(2011年12月14日)大于参数CreateDate,因此@endDate的记录不计算在内。< / p>

2 个答案:

答案 0 :(得分:9)

您可以随时执行以下操作:

select 
  (select count(*) from EmailTasks 
    where CreateDate between @beginDate and @endDate)
    as TotalEmails,
  (select count(*) from EmailTasks 
    where CreateDate between @beginDate and @endDate 
      and HasFailed = 1)
    as Failed,
  (select count(*) from EmailTasks 
    where CreateDate between @beginDate and @endDate 
      and HasFailed = 0)
    as Suceess

这将返回正确的值,但会对表执行三次,并且它的条件重复三次,因此如果逻辑被修改,则可能会出现粘贴错误。

如果HasFailed将始终为0或1(bit字段),您可以做到更聪明但不太清晰的解决方案:

  select 
    count(*) as TotalEmails, 
    sum(cast(HasFailed as int)) as Failed, 
    sum(1-cast(HasFailed as int)) as Suceess
  from EmailTasks 
    where CreateDate between @beginDate and @endDate 
  • 投标是必要的,因为sum运算符在bit字段无效,正如Martin Smith指出的那样

答案 1 :(得分:1)

试试这个SQL

select count(*) as TotalEmails, sum(HasFailed) as Failed, sum(1-HasFailed) as Success
 from EmailTasks where CreateDate between @beginDate and @endDate