How can I compare time in SQL Server?

I am trying to compare the time in a datetime field in an SQL query, but I do not know how it is right. I do not want to compare the date, part of the time.

I'm doing it:

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

Is it correct?

I ask about this because I need to know if '08: 00: 00 'is less or more than '07: 30: 00', and I don't want to compare the date, only part of the time.

Thank!

+48
sql datetime sql-server
Apr 30 '09 at 16:43
source share
16 answers

Your comparison will work, but it will be slow because the dates are converted to a string for each row. To effectively compare two parts of the time, try:

 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 

Long explanation: the date on the SQL server is stored as a floating point number. The digits before the decimal point represent the date. The numbers after the decimal point represent time.

So here is an example of a date:

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

Let me convert it to float:

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

Now take the part after the number, i.e. time:

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

Convert it back to datetime:

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

1900-01-01 is only a โ€œzeroโ€ date; you can display the temporary part with convert, specifying, for example, format 108, which is only time:

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

Conversions between datetime and float are pretty fast, because they are basically stored the same way.

+67
Apr 30 '09 at 18:55
source share
 convert(varchar(5), thedate, 108) between @leftTime and @rightTime 

Explanation:

if you have varchar(5) you will get HH:mm

if you have varchar(8) you get HH:mm ss

108 only gets time from SQL date

@leftTime and @rightTime are two variables to compare

+17
Apr 30 '09 at 17:02
source share

If you are using SQL Server 2008, you can do this:

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

Here's the full test:

 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) 
+11
Apr 30 '09 at 16:58
source share
 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)) 
+4
Jun 21 2018-12-12T00:
source share

One (possibly small) problem that I already spoke about with solutions is that they all require a function call to handle the comparison. This means that the query engine will have to do a full table scan to find the rows you are after - and you wonโ€™t be able to use the index. If the table is not particularly large, it probably will not have any negative consequences (and you can gladly ignore this answer).

If, on the other hand, the table can become quite large, query performance may suffer.

I know that you stated that you do not want to compare the date, but is there an actual date stored in the datetime column, or do you use it to store only time? If the latter, you can use a simple comparison operator, and this will reduce CPU usage and allow the query engine to use statistics and indexes (if any) to optimize the query.

If, however, the datetime column is used to store both the date and time of the event, this obviously will not work. In this case, if you can change the application and the table structure, divide the date and time into two separate datetime columns or create an indexed view that will select all (corresponding) columns of the original table, as well as the next column containing which you want to find (use any of the previous answers to calculate this) - and modify the application to request a view.

+3
Apr 30 '09 at 19:26
source share

Using float does not work.

 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)) 

You will see that the values โ€‹โ€‹do not match (SQL Server 2005). I wanted to use this method to check the time around midnight (the full method has more detailed information), in which I compared the current time between 23:55:00 and 00:05:00.

+3
Nov 02 '10 at 8:45
source share

Use Datepart function: DATEPART (datepart, date)

eg #

SELECT DatePart (@YourVar, hh) * 60) + DatePart (@YourVar, mi) * 60)

This will give you the total time of the day in minutes, allowing you to easily compare.

You can use DateDiff if your dates are the same, otherwise you will need to delete the date above

+2
Apr 30 '09 at 16:49
source share

Adding to other answers:

you can create a function to trim dates from datetime

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

So this is:

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

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

+2
Apr 30 '09 at 16:55
source share

Just change the conversion date and time to do the trick:

 SELECT timeEvent FROM tbEvents WHERE convert(time, startHour) >= convert(time, @startHour) 
+2
Dec 16 '14 at 23:50
source share

I believe you want to use DATEPART('hour', datetime) .

Link here:

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

+1
Apr 30 '09 at 16:50
source share

I donโ€™t like to rely on the insides of the repository (this is the date and time - this is a float with integer = day and fractional = time), but I do the same as Johnny D. Kano's answer. That is how I know all db developers. Definitely not convert to string. If you shouldn't handle it like float / int, then the best option is to pull an hour / minute / second / millisecond using DatePart ()

+1
Apr 30 '09 at 19:22
source share

You can create two datetime variables and set only the hour of the date you need to compare.

 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) 

The date will be "1900-01-01", you can compare it

 if @date1 <= @date2 print '@date1 less then @date2' else print '@date1 more then @date2' 
+1
Feb 11 '11 at 19:07
source share
 SELECT timeEvent FROM tbEvents WHERE CONVERT(VARCHAR,startHour,108) >= '01:01:01' 

This tells SQL Server to convert the current date / time to varchar using style 108, which is "hh: mm: ss". You can also replace '01: 01: 01 ', which if necessary converts another.

0
Apr 30 '09 at 16:49
source share

I assume your startHour column and @startHour variable are DATETIME; In this case, you should convert the string:

 SELECT timeEvent FROM tbEvents WHERE convert(VARCHAR(8), startHour, 8) >= convert(VARCHAR(8), @startHour, 8) 
0
Apr 30 '09 at 16:50
source share

below request gives you date time

 select DateAdd(day,-DateDiff(day,0,YourDateTime),YourDateTime) As NewTime from Table 
0
May 16 '11 at 13:18
source share

@ronmurp is a serious concern - the cast / floor approach returns different values โ€‹โ€‹at the same time. According to @littlechris answer and for a more general solution that resolves in a few minutes, seconds, a millisecond component, you can use this function to count the number of milliseconds since the beginning of the day.

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

I checked that it returns the same int for two different dates with the same time

 declare @first datetime set @first = '1900-01-01 23:59:39.090' declare @second datetime set @second = '2000-11-02 23:56:39.090' Select dbo.MsFromStartOfDay( @first ) Select dbo.MsFromStartOfDay( @second ) 

This solution does not always return the int you expect. For example, try below in SQL 2005, it returns an int ending in '557' instead of '556'.

 set @first = '1900-01-01 23:59:39.556' set @second = '2000-11-02 23:56:39.556' 

I think this is due to the fact that DateTime is stored as a float. However, you can compare two numbers. And when I used this approach in a โ€œrealโ€ DateTime dataset written in .NET using DateTime.Now () and stored in SQL, I found that the calculations were accurate.

0
Feb 02 '14 at 17:05
source share



All Articles