SQL Server에서 시간을 어떻게 비교할 수 있습니까?
SQL 쿼리 의 datetime 필드 에서 시간을 비교하려고하는데 그게 맞는지 모르겠습니다. 날짜 부분이 아니라 시간 부분 만 비교하고 싶습니다.
나는 이것을하고있다 :
SELECT timeEvent
FROM tbEvents
WHERE convert(datetime, startHour, 8) >= convert(datetime, @startHour, 8)
맞습니까?
내가 알고해야하기 때문에 나는이 부탁 해요 08:00:00
작거나 이상이다 07:30:00
내가 날짜, 바로 비교하고 싶지 않은 시간 부분.
감사!
비교는 작동하지만 날짜가 각 행의 문자열로 변환되므로 속도가 느려집니다. 두 시간 부분을 효율적으로 비교하려면 다음을 시도하십시오.
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 서버의 날짜는 부동 소수점 숫자로 저장됩니다. 소수점 앞의 숫자는 날짜를 나타냅니다. 소수점 뒤의 숫자는 시간을 나타냅니다.
다음은 날짜의 예입니다.
declare @mydate datetime
set @mydate = '2009-04-30 19:47:16.123'
float로 변환 해 보겠습니다.
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은 "제로"날짜입니다. 예를 들어 형식 108을 지정하여 변환을 사용하여 시간 부분을 표시 할 수 있습니다.
select convert(varchar(32),@mytime,108)
-- Shows 19:47:16
datetime과 float 간의 변환은 기본적으로 동일한 방식으로 저장되기 때문에 매우 빠릅니다.
convert(varchar(5), thedate, 108) between @leftTime and @rightTime
설명:
당신이있는 경우에 varchar(5)
당신이 얻을 것이다HH:mm
당신이 varchar(8)
얻는 다면HH:mm ss
108은 SQL 날짜에서 시간 만 얻습니다.
@leftTime
와 @rightTime
비교하는 두 변수는
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)
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))
지금까지 솔루션에서 언급 한 한 가지 (아마도 작은) 문제는 모두 비교를 처리하기 위해 함수 호출이 필요하다는 것입니다. 이는 쿼리 엔진이 사용자가 원하는 행을 찾기 위해 전체 테이블 스캔을 수행해야하며 인덱스를 사용할 수 없음을 의미합니다. 테이블이 특별히 커지지 않으면 부정적인 영향을 미치지 않을 것입니다 (이 대답을 기꺼이 무시할 수 있습니다).
반면에 테이블이 상당히 커지면 쿼리 성능이 저하 될 수 있습니다.
날짜 부분을 비교하고 싶지 않다고 말씀 하셨지만 datetime 열에 실제 날짜가 저장되어 있습니까? 아니면 시간 만 저장하는 데 사용하고 있습니까? 후자의 경우 간단한 비교 연산자를 사용할 수 있으며 이렇게하면 CPU 사용량이 모두 줄어들고 쿼리 엔진이 통계 및 인덱스 (있는 경우)를 사용하여 쿼리를 최적화 할 수 있습니다.
그러나 datetime 열이 이벤트의 날짜와 시간을 모두 저장하는 데 사용되는 경우 분명히 작동하지 않습니다. 이 경우 앱과 테이블 구조를 수정할 수있는 경우 날짜와 시간을 두 개의 개별 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 Server 2005). 이 방법을 사용하여 현재 시간을 23:55:00과 00:05:00 사이에 비교하는 자정 (전체 방법이 더 자세 함) 시간을 확인하고 싶었습니다.
트릭을 수행 해야하는 시간으로 변환 datetime을 변경하십시오.
SELECT timeEvent
FROM tbEvents
WHERE convert(time, startHour) >= convert(time, @startHour)
Adding to the other answers:
you can create a function for trimming the date from a datetime
CREATE FUNCTION dbo.f_trimdate (@dat datetime) RETURNS DATETIME AS BEGIN
RETURN CONVERT(DATETIME, CONVERT(FLOAT, @dat) - CONVERT(INT, @dat))
END
So this:
DECLARE @dat DATETIME
SELECT @dat = '20080201 02:25:46.000'
SELECT dbo.f_trimdate(@dat)
Will return 1900-01-01 02:25:46.000
Use Datepart function: DATEPART(datepart, date)
E.g#
SELECT DatePart(@YourVar, hh)*60) + DatePart(@YourVar, mi)*60)
This will give you total time of day in minutes allowing you to compare more easily.
You can use DateDiff if your dates are going to be the same, otherwise you'll need to strip out the date as above
You can create a two variables of datetime, and set only hour of date that your 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'
SELECT timeEvent
FROM tbEvents
WHERE CONVERT(VARCHAR,startHour,108) >= '01:01:01'
This tells SQL Server to convert the current date/time into a varchar using style 108, which is "hh:mm:ss". You can also replace '01:01:01' which another convert if necessary.
I believe you want to use DATEPART('hour', datetime)
.
Reference is here:
http://msdn.microsoft.com/en-us/library/ms174420.aspx
I don't love relying on storage internals (that datetime is a float with whole number = day and fractional = time), but I do the same thing as the answer Jhonny D. Cano. This is the way all of the db devs I know do it. Definitely do not convert to string. If you must avoid processing as float/int, then the best option is to pull out hour/minute/second/milliseconds with DatePart()
I am assuming your startHour column and @startHour variable are both DATETIME; In that case, you should be converting to a string:
SELECT timeEvent
FROM tbEvents
WHERE convert(VARCHAR(8), startHour, 8) >= convert(VARCHAR(8), @startHour, 8)
below query gives you time of the date
select DateAdd(day,-DateDiff(day,0,YourDateTime),YourDateTime) As NewTime from Table
@ronmurp raises a valid concern - the cast/floor approach returns different values for the same time. Along the lines of the answer by @littlechris and for a more general solution that solves for times that have a minute, seconds, milliseconds component, you could use this function to count the number of milliseconds from the start 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've verified 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 doesn't always return the int you would expect. For example, try the 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 has to do with the nature of DateTime stored as float. You can still compare the two number, though. And when I used this approach on a "real" dataset of DateTime captured in .NET using DateTime.Now() and stored in SQL, I found that the calculations were accurate.
참고URL : https://stackoverflow.com/questions/807909/how-can-i-compare-time-in-sql-server
'program tip' 카테고리의 다른 글
MockitoJUnitRunner는 더 이상 사용되지 않습니다. (0) | 2020.12.11 |
---|---|
C ++ 정적 초기화 순서 문제 찾기 (0) | 2020.12.11 |
int 대신 string :: size_type (0) | 2020.12.11 |
SQLite“INSERT OR REPLACE INTO”vs.“UPDATE… WHERE” (0) | 2020.12.11 |
printf ()를 사용하는 소수점 두 자리 (0) | 2020.12.11 |