我尝试在 查询中比较SQL字段 中的时间,但我不知道它是否正确。我不想比较日期部分,只比较时间部分。
我正在做这个:
SELECT timeEvent
FROM tbEvents
WHERE convert(datetime, startHour, 8) >= convert(datetime, @startHour, 8)
这是正确的吗?
我之所以这样问,是因为我需要知道
08:00:00
是小于还是大于
07:30:00
,我不想比较日期,只想比较
time
部分。
谢谢!
加上其他答案:
可以创建一个函数来修剪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
如果您使用的是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)
您的比较将有效,但它将很慢,因为日期被转换为每一行的字符串。要有效地比较两个时间部分,请尝试:
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之间的转换非常快,因为它们基本上是以相同的方式存储的。
到目前为止,我在解决方案中注意到的一个(可能很小的)问题是,它们似乎都需要一个函数调用来处理比较。这意味着查询引擎将需要执行全表扫描来查找您要查找的行-并且无法使用索引。如果表不会变得特别大,这可能不会有任何不利影响(您可以很高兴地忽略这个答案)。
另一方面,如果表可能变得非常大,查询的性能可能会受到影响。
我知道您说过您不希望比较日期部分-但是datetime列中是否存储了实际的日期,或者您是否只使用它来存储时间?如果是后者,您可以使用简单的比较运算符,这将减少CPU使用率,并允许查询引擎使用统计信息和索引(如果存在)来优化查询。
但是,如果datetime列同时用于存储事件的日期和时间,那么这显然是行不通的。在这种情况下,如果您可以修改应用程序和表结构,请将日期和时间分离到两个单独的日期时间列中,或者创建一个索引视图来选择源表的所有(相关)列,以及包含您希望搜索的时间元素的另一列(使用之前的任何答案来计算)-并更改应用程序以查询视图。
使用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之间的当前时间。
您可以创建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'
@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
|
|
开心的地瓜 · influxdb 查询慢-掘金 2 年前 |