Sql Server,如何在上个月记录的记录中返回结果?

时间:2013-05-07 22:08:55

标签: sql sql-server select between

我正在尝试返回上个月完成标记的所有记录的计数。列名称是他的日期时间字段。这是我需要确保记录在上个月完成的相同字段。

这就是我所拥有的

SELECT count(*) 
FROM PhoneCall AS p WITH (nolock) 
WHERE   ( p.actualend >= CAST(CONVERT(varchar(8), DATEADD(dd, - (DAY(DATEADD(mm, 1, GETDATE())) - 1), DATEADD(mm, - 1, GETDATE())), 1) AS datetime)) 
  AND ( p.actualend <= CAST(CONVERT(varchar(8), DATEADD(s, -1, DATEADD(mm, DATEDIFF(m, 0, GETDATE()), 0)), 1) AS datetime))

这段代码给了我稍微高一点的结果(总得分为847)

但如果我运行此代码

SELECT count(*) 
FROM PhoneCall AS p WITH (nolock) 
WHERE p.actualend BETWEEN '03/01/2013 00:00:00' AND '03/31/2013 23:59:59' 

我总共获得了843条记录。 如何更正我的第一个查询以在两个查询中获得相同的总数?

由于

2 个答案:

答案 0 :(得分:1)

您的第一个查询未获得最后一天标记的所有记录。这是因为最后一天的计算返回正确的日期,时间是凌晨12:00:00。你希望时间部分是晚上11:59:59。

为了测试查询中的逻辑,我运行了一个select语句来查看上个月第一天和最后一天的计算结果:

select CAST(CONVERT(varchar(8), DATEADD(dd, - (DAY(DATEADD(mm, 1, GETDATE())) - 1), DATEADD(mm, - 1, GETDATE())), 1) AS datetime)
select CAST(CONVERT(varchar(8), DATEADD(s, -1, DATEADD(mm, DATEDIFF(m, 0, GETDATE()), 0)), 1) AS datetime)

结果为2013-04-01 00:00:00.0002013-04-30 00:00:00.000。 (根据当前日期2013年5月7日)

我建议计算当月的第一天而不是上个月的最后一天,然后进行<比较而不是<=比较。那么你就不必处理如果记录在当天的最后几毫秒完成标记后会发生什么。

我通过在月末计算中添加1天来修改您的原始查询 - 有效地计算当月的第一天。然后我将比较运算符更改为1而不是<=。您可能可以改进此计算,但这只是一种快速简便的方法来显示逻辑示例。

SELECT count(*) 
FROM PhoneCall AS p WITH (nolock) 
WHERE ( p.actualend >= CAST(CONVERT(varchar(8), DATEADD(dd, - (DAY(DATEADD(mm, 1, GETDATE())) - 1), DATEADD(mm, - 1, GETDATE())), 1) AS datetime))
  AND ( p.actualend < CAST(CONVERT(varchar(8), DATEADD(s, -1, DATEADD(mm, DATEDIFF(m, 0, GETDATE()), 0)), 1) AS datetime) + 1)

答案 1 :(得分:1)

亚当有一个正确的答案。但是,我认为可以通过这种方式使其更容易理解。

在两个日期之间选择数据的要点是使用这个逻辑,这是在Adam的第二个查询中。

where YourField >= @StartDate
and YourField < the day after @EndDate

如果从应用程序(.net,php,coldfusion等)调用此查询,则在应用程序中创建这些变量并将其作为参数发送可能更为简单。否则,您可能想要这样做:

  declare @EndDate as datetime;
  declare @StartDate as datetime;

  set @EndDate = CAST(CONVERT(varchar(8)
  , DATEADD(dd, - (DAY(DATEADD(mm, 1, GETDATE())) - 1)
 , DATEADD(mm, 0, GETDATE())), 1) AS datetime);

 set @StartDate = DateAdd(month, -1, @EndDate);

 SELECT count(*) 
 FROM lassqls1.CareCredit_MSCRM.dbo.PhoneCall AS p WITH (nolock) 
 WHERE p.actualend >= @StartDate
 and p.actualend < @EndDate