相关文章推荐
开心的地瓜  ·  influxdb 查询慢-掘金·  2 年前    · 
小胡子的日光灯  ·  nuxt ...·  2 年前    · 
登录

如何在SQL Server中比较时间?

内容来源于 Stack Overflow,遵循 CC BY-SA 4.0 许可协议进行翻译与使用。IT领域专用引擎提供翻译支持

腾讯云小微IT领域专用引擎提供翻译支持

原文
Stack Overflow用户 修改于2018-11-22
  • 该问题已被编辑
  • 提问者: Stack Overflow用户
  • 提问时间: 2009-04-30 16:43

我尝试在 查询中比较SQL字段 中的时间,但我不知道它是否正确。我不想比较日期部分,只比较时间部分。

我正在做这个:

SELECT timeEvent 
FROM tbEvents 
WHERE convert(datetime, startHour, 8) >= convert(datetime, @startHour, 8)

这是正确的吗?

我之所以这样问,是因为我需要知道 08:00:00 是小于还是大于 07:30:00 ,我不想比较日期,只想比较 time 部分。

谢谢!

浏览 544 关注 0 得票数 64
  • 得票数为Stack Overflow原文数据
原文
修改于2009-04-30
  • 该回答已被编辑
  • 回答者: Stack Overflow用户
  • 回答时间: 2009-04-30 16:49
得票数 2

使用Datepart函数: DATEPART (datepart,date)

E.g#

选择DatePart(@YourVar,hh)*60) + DatePart(@YourVar,mi)*60)

这将提供以分钟为单位的一天中的总时间,使您可以更轻松地进行比较。

如果日期相同,则可以使用DateDiff,否则需要去掉上面的日期

回答于2009-04-30
得票数 1
SELECT timeEvent 
  FROM tbEvents 
 WHERE CONVERT(VARCHAR,startHour,108) >= '01:01:01'

这将告知SQL Server使用样式108将当前日期/时间转换为varchar,即"hh:mm:ss“。如果需要,您也可以替换为'01:01:01‘,这是另一个转换。

回答于2009-04-30
得票数 1

我相信你想使用 DATEPART('hour', datetime)

参考资料在这里:

http://msdn.microsoft.com/en-us/library/ms174420.aspx

操作
回答于2009-04-30
得票数 0

我假设您的startHour列和@startHour变量都是DATETIME;在这种情况下,您应该转换为字符串:

SELECT timeEvent
FROM tbEvents
WHERE convert(VARCHAR(8), startHour, 8) >= convert(VARCHAR(8), @startHour, 8)
Stack Overflow用户
回答于2009-04-30
得票数 2

加上其他答案:

可以创建一个函数来修剪datetime中的日期

CREATE FUNCTION dbo.f_trimdate (@dat datetime) RETURNS DATETIME AS BEGIN
    RETURN CONVERT(DATETIME, CONVERT(FLOAT, @dat) - CONVERT(INT, @dat))
END

所以这就是:

DECLARE @dat DATETIME
SELECT @dat = '20080201 02:25:46.000'
SELECT dbo.f_trimdate(@dat)

将return 1900-01-01 02:25:46.000

回答于2009-04-30
得票数 15

如果您使用的是SQL Server 2008,则可以执行以下操作:

WHERE CONVERT(time(0), startHour) >= CONVERT(time(0), @startTime)

下面是一个完整的测试:

DECLARE @tbEvents TABLE (
    timeEvent   int      IDENTITY,
    startHour   datetime
INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 0, GETDATE())
INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 1, GETDATE())
INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 2, GETDATE())
INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 3, GETDATE())
INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 4, GETDATE())
INSERT INTO @tbEvents (startHour) SELECT DATEADD(hh, 5, GETDATE())
--SELECT * FROM @tbEvents
DECLARE @startTime  datetime
SET @startTime = DATEADD(mi, 65, GETDATE())
SELECT
    timeEvent,
    CONVERT(time(0), startHour)  AS 'startHour',
    CONVERT(time(0), @startTime) AS '@startTime'
FROM @tbEvents
WHERE CONVERT(time(0), startHour) >= CONVERT(time(0), @startTime)
修改于2013-01-30
  • 该回答已被编辑
  • 回答者: Stack Overflow用户
  • 回答时间: 2009-04-30 17:02
得票数 19
convert(varchar(5), thedate, 108) between @leftTime and @rightTime

解释:

如果您有 varchar(5) ,您将获得 HH:mm

如果你有 varchar(8) ,你就会得到 HH:mm ss

108仅从SQL日期获取时间

@leftTime @rightTime 是两个要比较的变量

修改于2021-04-21
  • 该回答已被编辑
  • 回答者: Stack Overflow用户
  • 回答时间: 2009-04-30 18:55
得票数 80

您的比较将有效,但它将很慢,因为日期被转换为每一行的字符串。要有效地比较两个时间部分,请尝试:

declare @first datetime
set @first = '2009-04-30 19:47:16.123'
declare @second datetime
set @second = '2009-04-10 19:47:16.123'
select (cast(@first as float) - floor(cast(@first as float))) -
       (cast(@second as float) - floor(cast(@second as float)))
       as Difference

详细说明: SQL server中的日期存储为浮点数。小数点前的数字表示日期。小数点后的数字表示时间。

下面是一个示例日期:

declare @mydate datetime
set @mydate = '2009-04-30 19:47:16.123'

让我们将它转换为一个浮点数:

declare @myfloat float
set @myfloat = cast(@mydate as float)
select @myfloat
-- Shows 39931,8244921682

现在取逗号后面的部分,即时间:

set @myfloat = @myfloat - floor(@myfloat) 
select @myfloat
-- Shows 0,824492168212601

将其转换回datetime:

declare @mytime datetime
set @mytime = convert(datetime,@myfloat)
select @mytime
-- Shows 1900-01-01 19:47:16.123

1900-01-01只是“零”日期;您可以使用convert显示时间部分,例如指定格式108,这就是时间:

select convert(varchar(32),@mytime,108)
-- Shows 19:47:16

datetime和float之间的转换非常快,因为它们基本上是以相同的方式存储的。

回答于2009-04-30
得票数 1

我不喜欢依赖存储内部( datetime是一个整数= day,小数=time的浮点数),但我做的事情与答案Jhonny D.Cano相同。我认识的所有数据库开发人员都是这样做的。绝对不要转换成字符串。如果必须避免作为浮点型/整型处理,那么最好的选择是使用DatePart()提取小时/分钟/秒/毫秒

Stack Overflow用户
修改于2010-07-07
  • 该回答已被编辑
  • 回答者: Stack Overflow用户
  • 回答时间: 2009-04-30 19:26
得票数 4

到目前为止,我在解决方案中注意到的一个(可能很小的)问题是,它们似乎都需要一个函数调用来处理比较。这意味着查询引擎将需要执行全表扫描来查找您要查找的行-并且无法使用索引。如果表不会变得特别大,这可能不会有任何不利影响(您可以很高兴地忽略这个答案)。

另一方面,如果表可能变得非常大,查询的性能可能会受到影响。

我知道您说过您不希望比较日期部分-但是datetime列中是否存储了实际的日期,或者您是否只使用它来存储时间?如果是后者,您可以使用简单的比较运算符,这将减少CPU使用率,并允许查询引擎使用统计信息和索引(如果存在)来优化查询。

但是,如果datetime列同时用于存储事件的日期和时间,那么这显然是行不通的。在这种情况下,如果您可以修改应用程序和表结构,请将日期和时间分离到两个单独的日期时间列中,或者创建一个索引视图来选择源表的所有(相关)列,以及包含您希望搜索的时间元素的另一列(使用之前的任何答案来计算)-并更改应用程序以查询视图。

操作
修改于2011-12-18
  • 该回答已被编辑
  • 回答者: Stack Overflow用户
  • 回答时间: 2010-11-02 16:45
得票数 3

使用float不起作用。

DECLARE @t1 datetime, @t2 datetime
SELECT @t1 = '19000101 23:55:00', @t2 = '20001102 23:55:00'
SELECT CAST(@t1 as float) - floor(CAST(@t1 as float)), CAST(@t2 as float) - floor(CAST(@t2 as float))

您将看到这些值不同(SQL Server2005)。我想使用这个方法来检查午夜前后的时间( full方法有更多细节),其中我比较了23:55:00和00:05:00之间的当前时间。

操作
回答于2011-02-12
得票数 2

您可以创建datetime的两个变量,并只设置需要比较的日期小时。

declare  @date1 datetime;
declare  @date2 datetime;
select   @date1 = CONVERT(varchar(20),CONVERT(datetime, '2011-02-11 08:00:00'), 114)
select   @date2 = CONVERT(varchar(20),GETDATE(), 114)

日期是"1900-01-01“,你可以比较一下

if @date1 <= @date2
   print '@date1 less then @date2'
   print '@date1 more then @date2'
修改于2012-01-02
  • 该回答已被编辑
  • 回答者: Stack Overflow用户
  • 回答时间: 2011-05-16 21:18
得票数 0

下面的查询显示日期的时间

select DateAdd(day,-DateDiff(day,0,YourDateTime),YourDateTime) As NewTime from Table
操作
修改于2012-06-22
  • 该回答已被编辑
  • 回答者: Stack Overflow用户
  • 回答时间: 2012-06-22 04:08
得票数 4
if (cast('2012-06-20 23:49:14.363' as time) between 
    cast('2012-06-20 23:49:14.363' as time) and 
    cast('2012-06-20 23:49:14.363' as time))
0
回答于2014-02-03
得票数 0

@ronmurp提出了一个合理的问题-- cast/floor方法在同一时间返回不同的值。按照@littlechris的答案,对于具有分钟、秒、毫秒分量的时间的更一般的解决方案,您可以使用此函数来计算从一天开始的毫秒数。

Create Function [dbo].[MsFromStartOfDay] ( @DateTime datetime )
Returns int
  Begin
      Return (
               ( Datepart( ms , @DateTime ) ) +
               ( Datepart( ss , @DateTime ) * 1000 ) +
               ( Datepart( mi , @DateTime ) * 1000 * 60 ) +
               ( Datepart( hh , @DateTime ) * 1000 * 60 * 60 )
  End

我已经验证了,对于相同时间的两个不同日期,它返回相同的int

declare @first datetime
set @first = '1900-01-01 23:59:39.090'
declare @second datetime