SQL DateTime을 자정으로 반올림


81

SQL 쿼리에 작은 문제가 있습니다. GETDATE 함수를 사용하고 있지만 오후 5시에 스크립트를 실행한다고 가정하면 2011 년 12 월 12 일 오후 5 시부 터 2011 년 12 월 18 일 오후 5시 사이에 레코드를 가져옵니다. 어떻게하면 전체 2011 년 12 월 12 일부터 2011 년 12 월 18 일까지 전체에 대한 기록을 가져올 수 있지만 기본적으로 시간을 무시합니다.

내 스크립트 :

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate > (GETDATE()-6)  

답변:


114

SQL Server 2008 이상에서는 DateTime을으로 캐스트 Date하여 시간 요소를 제거 할 수 있습니다 .

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate >= (cast(GETDATE()-6 as date))  

SQL Server 2005 이하에서는 다음을 사용할 수 있습니다.

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate >= DateAdd(Day, Datediff(Day,0, GetDate() -6), 0)

1
이 유형 날짜가 정의 된 시스템 유형이 아닙니다.
henryaaron

2
난 당신이 :) 다음 SQL 2008를 사용하지 않을 생각
DaveShaw

@ user1090389이 내가 문자열 변환 옵션을 넣어 이유의; D
바삼 Mehanni

@DaveShaw-거기에 DATEADD 누락
MatBailie dec.

죄송합니다 @Dems 데이브의 모습은 덜 복잡
henryaaron을

54

내가 찾은 가장 간단한 것은

-- Midnight floor of current date

SELECT Convert(DateTime, DATEDIFF(DAY, 0, GETDATE()))

DATEDIFF는 1900-1-1 이후의 정수 일 수를 반환하고 Convert Datetime은 의무적으로 자정의 해당 날짜로 다시 가져옵니다.

DateDiff는 정수를 반환하므로 날짜를 더하거나 빼서 올바른 오프셋을 얻을 수 있습니다.

SELECT Convert(DateTime, DATEDIFF(DAY, 0, GETDATE()) + @dayOffset)

이것은 반올림이 아닙니다. 이것은 잘립니다. 그러나 나는 그것이 요구되는 것이라고 생각합니다. (반올림하려면 1을 더하고 자르십시오 ... 그리고 그것은 또한 반올림이 아닙니다. 그 천장을 반올림하지만 다시 한 번 당신이 원하는 것입니다. 정말로 반올림하려면 .5를 더하고 (작동합니까?) 자르십시오.

GetDate ()에 .5를 추가 할 수 있으며 예상대로 작동합니다.

-- Round Current time to midnight today or midnight tomorrow

SELECT Convert(DateTime, DATEDIFF(DAY, 0, GETDATE() + .5))

SQL Server 2008에서 모든 시도를 수행했지만 이러한 기능이 2005에도 적용되는 것 같습니다.


이것은 2k5에서 작동합니다. where [ScanDate] >= convert(datetime, datediff(day, 0, getdate())) and [ScanDate] < convert(datetime, datediff(day, -1, getdate()))
nulltron

9
--
-- SQL DATEDIFF getting midnight time parts 
--
SELECT GETDATE() AS Now, 
   Convert(DateTime, DATEDIFF(DAY, 0, GETDATE())) AS MidnightToday,
   Convert(DateTime, DATEDIFF(DAY, -1, GETDATE())) AS MidnightNextDay,
   Convert(DateTime, DATEDIFF(DAY, 1, GETDATE())) AS MidnightYesterDay
go
Now                   MidnightToday          MidnightNextDay        MidnightYesterDay     
 --------------------  ---------------------  ---------------------  --------------------- 
 8/27/2014 4:30:22 PM  8/27/2014 12:00:00 AM  8/28/2014 12:00:00 AM  8/26/2014 12:00:00 AM 

5
SELECT getdate()

결과 : 2012-12-14 16 : 03 : 33.360

SELECT convert(datetime,convert(bigint, getdate()))

결과 2012-12-15 00 : 00 : 00.000


1
피드백 주셔서 감사합니다. 내가 강조하려는 것은 bigint 로의 변환이 당신을 위해 반올림을 수행한다는 것입니다.
Jeremy Atkinson

1
이 코드는 시간이 정오 이후 인 경우 하루가 끝날 때 자정까지 반올림하여 반나절 동안 잘못되었습니다.
ChrisM

이 방법을 사용하면 나중에 더 큰 데이터 세트에서 성능에 영향을 미칠 수 있습니다.
Taco タ コ ス

3

@BassamMehanni가 언급했듯이 SQL Server 2008부터 DATE로 캐스팅 할 수 있습니다.

SELECT
  *
FROM
  yourTable
WHERE
      dateField >= CAST(GetDate() - 6 AS DATE)
  AND dateField <  CAST(GetDate() + 1 AS DATE)

두 번째 조건은 실제로 그냥 GetDate()일 수 있지만 Less Than DateXdateField를 DATE로 캐스팅하지 않아도되므로 성능이 크게 향상되는 것을 방지하기 위한 예로이 형식을 보여줍니다 .


2005 년 이하라면 이것을 사용할 수 있습니다 ...

SELECT
  *
FROM
  yourTable
WHERE
      dateField >= DATEADD(DAY, DATEDIFF(DAY, 0, GetDate()) - 6, 0)
  AND dateField <  DATEADD(DAY, DATEDIFF(DAY, 0, GetDate()) + 1, 0)

3

이것을 사용해보십시오.

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate >= CONVERT(DATE, GETDATE())

1

이것은 싸게 보일지 모르지만 그것은 나를 위해 일합니다

SELECT CONVERT (DATETIME, LEFT (CONVERT (VARCHAR, @ dateFieldOrVariable, 101), 10) + '00 : 00 : 00.000')


1

datetime을 날짜로 변환 한 다음 다시 datetime으로 변환 할 수 있습니다. 타임 스탬프가 재설정됩니다.

getdate () 선택 --2020-05-05 13 : 53 : 35.863

선택 cast (cast (GETDATE () as date) as datetime) --2020-05-05 00 : 00 : 00.000

0

나는 보통

SELECT *
FROM MyTable
WHERE CONVERT(VARCHAR, MyTable.dateField, 101) = CONVERT(VARCHAR, GETDATE(), 101)

SQL SERVER 2008을 사용하는 경우 다음을 수행 할 수 있습니다.

SELECT *
FROM MyTable
WHERE CAST(MyTable.dateField AS DATE) = CAST(GETDATE() AS DATE)

도움이 되었기를 바랍니다


3
첫 번째 예를 사용하면 옵티마이 저가 인덱스 등을 사용하는 능력을 파괴 합니다. 문자열 함수를 사용하여 날짜 산술 및 비교를 수행하는 것은 매우 나쁜 생각입니다. 그것은 결코 언급되어서는 안되며 (imo) 옵션이 좋지 않습니다.
MatBailie 2011

SQL Server 2008을 사용하고 있다면 그럴 필요가 없습니다. 그렇지 않으면 SQL Server 2000/2005에서 어떻게 할 수 있는지 잘 모르겠습니다. 예를 들어 감사하겠습니다.
Bassam Mehanni

공정하다. 두 옵션 모두 optmizer의 인덱스 사용 기능을 파괴합니다. 필터 조건 자 열에서 수행하고 기능을 수행해야합니다. 여기에는 캐스트가 포함됩니다.
pim

0

시간을 반올림 할 수 있습니다.

ROUND아래를 사용하면 자정으로 반올림됩니다.

WHERE Orders.OrderStatus = 'Shipped'  
AND Orders.ShipDate >  CONVERT(datetime, (ROUND(convert(float, getdate()-6.5),0)))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.