【问题标题】:Weird Time Difference in SQL ServerSQL Server 中奇怪的时差
【发布时间】:2015-08-10 05:58:24
【问题描述】:

我有一个如下所述的 SQL 表,其中包含每 30 分钟执行的 1 条记录以及其他一些列 -

ID | dt
1  | 2015-08-08 23:30:00.000
2  | 2015-08-08 23:00:00.000
3  | 2015-08-08 22:30:00.000
4  | 2015-08-08 22:00:00.000
5  | 2015-08-08 21:30:00.000

我运行以下查询以从 SQL Server 获取昨天的所有记录。

select ID, dt from tbl1
WHERE  DATEADD(dd, DATEDIFF(dd, 0, dt), 0) >= DATEADD(dd, DATEDIFF(dd, 0, @StartDate), 0) 
and DATEADD(dd, DATEDIFF(dd, 0, dt), 0) <= DATEADD(dd, DATEDIFF(dd, 0, @EndDate), 0)

当我将参数发送为 StartDate = '2015-08-08 12:00:00' and EndDate='2015-08-08 06:30:00' 时,查询运行正常并返回结果,但当 StartDate = '2015-08-08 12:00:00' and EndDate='2015-08-08 06:00:00' 或 EndDate 明确小于“2015-08-08 06:30:00”时,它不返回任何记录。我在服务器上运行了SELECT GETDATE(),它返回的时间与服务器时钟显示的时间相同。

编辑

代码通过每 30 分钟运行一次的 Windows 服务执行。假设应用程序在凌晨 1:00 运行,检索上次日期的记录并执行操作,但如前所述,记录仅在上午 6:30 后返回,目前我被困在早上 7 点运行服务而不是凌晨 1 点。

当我将服务设置为从本地计算机运行时,它会在凌晨 1 点运行良好并返回结果,但在生产服务器上,它不会在早上 6:30 之前返回任何记录。

我不知道为什么会发生这种差异。任何帮助表示赞赏。

如果您需要更多说明,我会在这里回答。

【问题讨论】:

  • dt 列是 DateTime 格式还是 varchar 格式?
  • @Nitesh 对我来说效果很好,它显示了所有 5 条记录,其中包含两个 EndDate 值。
  • @CiucaS,它适用于我的本地计算机,但不适用于我无权访问的生产服务器。它在 prod 上运行良好,但仅在上午 6:30 之后而不是之前。我很困惑,因为无论参数值是什么,我都将查询中的所有 dt 列、startdate、enddate 更改为“2015-08-08 00:00:00”。
  • 为什么不将@StarDate 转换为DATE 而不是使用DATEADD/DATEDIFF`/
  • SQLFiddle 的行为与您描述的不同。 sqlfiddle.com/#!3/466aa/5/0您提供的示例数据未发现该问题。如果您获得的结果使用的数据与您在此处显示的数据不同,您可能需要分享这些数据,以便我们进一步帮助您。

标签: c# sql sql-server sql-server-2012


【解决方案1】:

您最初问为什么当@StartDate 是“2015-08-08 12:00:00”和@EndDate 是“2015-08-08 06:30:00”时没有收到任何记录。请理解,在这种情况下,@StartDate@EndDate 之后,因此您永远不会得到大于@StartDate 和小于@EndDatedt 值。

话虽如此,您显然想使用 @StartDate@EndDate 参数的 FLOOR(即忽略时间部分)而不是原始使用它们,所以您可以做什么:

  • 仅向下舍入 @StartDate@EndDate 参数
  • @EndDate添加一天
  • tbl 中选择所有记录,其中dt 在修改后的@StartDate@EndDate 之间
    • 适当调整运算符以包含/排除@EndDate 的确切值

此示例假定您的代码作为存储过程的一部分被调用,并且将选择所有大于或等于 @StartDate 但小于 @EndDate 的日期(您不需要对dt):

-- Swap @StartDate and @EndDate values if need be
IF(@StartDate > @EndDate)
BEGIN
    DECLARE @TempDate DATETIME;
    SET @TempDate = @StartDate;
    SET @StartDate = @EndDate;
    SET @EndDate = @TempDate;
END;

-- Deliberately set @EndDate to one more than specified
-- Example case:
--                Before                   After
--     @StartDate '2015-08-08 06:30:00' => '2015-08-08 00:00:00'
--     @EndDate   '2015-08-08 12:00:00' => '2015-08-09 00:00:00'
SET @StartDate = dateadd(day,datediff(day,0,@StartDate),0);
SET @EndDate = dateadd(day,datediff(day,0,@StartDate)+1,0);

-- Query
select ID, dt from tbl1
WHERE dt >= @StartDate 
and dt < @EndDate

【讨论】:

  • 如果我理解正确,为什么我在 startdate='2015-08-08 12:00:00' 和 enddate = '2015-08-08 07:00:00' 时获取数据
  • 我假设您想将开始/结束日期四舍五入到一整天,并且如果前者大于后者,您想交换 @StartDate@EndDate。跨度>
  • 至于为什么你在@StartDate = '2015-08-08 12:00' 和@EndDate = '2015-08-08 07:00' 时得到数据,很可能是你的数据库可能配置为将时间视为 12 小时,如果未指定,则假定为 AM - 例如,12:00 (AM) » 0:00 24hr。我建议返回最高/最低 dt 值来强化您的问题。
  • 您可能会说我最初假设“12:00”是中午 12 点,而不是上午 12 点。 :$
  • 我最初是这么认为的:)
猜你喜欢
  • 2013-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多