SQL Server에서 날짜 시간을 자르려면 어떻게해야합니까?


281

SQL Server 2008에서 날짜 시간 값을 자르는 가장 좋은 방법은 무엇입니까 (시간 및 분 제거)?

예를 들면 다음과 같습니다.

declare @SomeDate datetime = '2009-05-28 16:30:22'
select trunc_date(@SomeDate)

-----------------------
2009-05-28 00:00:00.000

답변:


495

이것은 몇 년이 지난 후에도 계속해서 추가 투표를 수집하므로 최신 버전의 Sql Server에 대해 업데이트해야합니다. Sql Server 2008 이상의 경우 다음과 같이 간단합니다.

cast(getDate() As Date)

하단 근처의 마지막 세 단락은 여전히 ​​적용되며, 한 걸음 물러서서 먼저 캐스트를 피할 수있는 방법을 찾아야합니다.

그러나 이것을 달성하는 다른 방법들도 있습니다. 가장 일반적인 것은 다음과 같습니다.

올바른 방법 (Sql Server 2008 이후의 새로운 기능) :

cast(getdate() As Date)

올바른 방법 (이전) :

dateadd(dd, datediff(dd,0, getDate()), 0)

현재는 오래되었지만 월, 분, 시간 또는 연도의 첫 번째 순간과 같은 다른 시점에도 쉽게 적응할 수 있기 때문에 여전히 알 가치가 있습니다.

이 올바른 방법은 ANSI 표준의 일부이며 작동이 보장되는 문서화 된 기능을 사용하지만 다소 느려질 수 있습니다. 0 일부터 현재 날짜까지 며칠이 지 났는지 확인하고 0 일까지 며칠을 추가하여 작동합니다. 날짜 시간이 어떻게 저장되는지, 로케일이 무엇이든 관계없이 작동합니다.

빠른 길 :

cast(floor(cast(getdate() as float)) as datetime)

날짜 시간 열이 8 바이트 이진 값으로 저장되기 때문에 작동합니다. 플로팅으로 캐스트하고, 분수를 제거하기 위해 플로어하고, 날짜 / 시간으로 다시 캐스트 할 때 값의 시간 부분이 사라집니다. 복잡한 논리없이 조금만 이동하고 매우 빠릅니다.

이는 자동 서비스 업데이트에서도 Microsoft가 언제든지 변경할 수있는 구현 세부 사항에 의존합니다. 또한 휴대하기가 쉽지 않습니다. 실제로이 구현이 곧 변경 될 가능성은 거의 없지만, 사용하기로 선택한 경우 여전히 위험에 대해 알고 있어야합니다. 이제 날짜로 전송할 수있는 옵션이 있으므로 거의 필요하지 않습니다.

잘못된 방법 :

cast(convert(char(11), getdate(), 113) as datetime)

잘못된 방법은 문자열로 변환하고 문자열을 자르고 날짜 시간으로 다시 변환하여 작동합니다. 그것은 두 가지 이유로 잘못 되었습니다 : 1) 모든 로케일에서 작동하지 않을 수도 있고 2)이 작업을 수행하는 가장 느린 방법에 관한 것입니다. 다른 옵션보다 한두 배 정도 느립니다.


업데이트 최근에 일부 투표가 이루어 졌으므로이 게시물을 게시 한 후 Sql Server가 "올바른"방법과 "빠른"방법 간의 성능 차이를 최적화 할 것이라는 확실한 증거를 보았습니다. , 이제 이전을 선호해야합니다.

두 경우 모두 처음부터이 작업을 수행 할 필요가 없도록 쿼리를 작성하려고합니다 . 데이터베이스에서이 작업을 수행해야하는 경우는 매우 드 rare니다.

대부분의 경우 데이터베이스는 이미 병목 현상입니다. 일반적으로 성능 향상을 위해 하드웨어를 추가하는 것이 가장 비용이 많이 드는 서버이며 추가 기능을 제대로 적용하기 가장 어려운 서버입니다 (예를 들어 디스크와 메모리의 균형을 조정해야 함). 또한 기술적으로나 비즈니스 관점에서 볼 때 외부로 확장하기가 가장 어렵습니다. 기술적으로 데이터베이스 서버보다 웹 또는 응용 프로그램 서버를 추가하는 것이 훨씬 쉽고, 그것이 거짓 인 경우에도 IIS 또는 Apache의 서버 라이센스 당 $ 20,000 +를 지불하지 않습니다.

내가하려고하는 요점은 가능하면 응용 프로그램 수준 에서이 작업을 수행해야한다는 것입니다. 단지 당신이 하루에 의해 그룹에 필요, 심지어 그때는 아마 삽입 / 업데이트시에 유지되는 계산 열로 설정 여분의 열을해야하거나 유지 관리 할 때 당신이 이제까지 자신의 SQL Server에서 날짜를 절단 찾아야 할 때입니다 응용 로직에서. 이 인덱스를 깨고 CPU가 많은 작업을 데이터베이스에서 수행하십시오.


6
"빠른 방법"은 방금 실행 한 벤치 마크에 따라 SQL 2008에 가장 빠른 방법입니다.
Sam Saffron

3
참고 : stackoverflow.com/q/1177449/27535stackoverflow.com/q/133081/27535 dateadd / datediff는 "승리합니다 ...". 물론 하나의 변수에 관심이 있고 열 또는 백만 개가 넘는 행을 계산했으면
좋겠습니다.

9
이 "올바른"방법은 우연히 작동합니다. 작성 방법은 DateAdd의 구문이 (간격, 날짜, 증분) 인 것처럼 보이지만 그렇지 않습니다. (간격, 증분, 날짜)입니다. SELECT DATEADD (m, 0, DATEDIFF (m, 0, GETDATE ()))는 작동하지 않지만 SELECT DATEADD (m, DATEDIFF (m, 0, GETDATE (), 0)이 수행합니다. 적어도 이것이 2008R2에서 보는 것입니다.
켈리 클라인

1
2008R2의 @Kelly, 왜 안 cast(getdate() as date)됩니까?
Joel Coehoorn 님이

2
그들은 모두 날짜 시간 열에서 작동합니다. getdate()다음은 날짜 / 시간 소스에 관계없이 제공됩니다.
Joel Coehoorn

44

SQL Server 2008 전용

CAST(@SomeDateTime AS Date) 

그런 다음 원하는 경우 날짜 시간으로 다시 캐스팅하십시오.

CAST(CAST(@SomeDateTime AS Date) As datetime)

좋은 점 : 저는 여전히 2005 년에 있으며 2008 년에는 이것이 새로운 "올바른"방법 일 수도 있고 "빠른"방법의 성능과 일치 할 수도 있습니다.
Joel Coehoorn

1
이 새로운 방식의 성능은 "빠른"방식보다 훨씬 빠릅니다.
ErikE

21

보다 완벽한 대답을 위해 다음과 같이 날짜 부분을 자르고 분을 포함 GETDATE()하여 잘릴 수있는 효과적인 방법이 있습니다 (자르는 날짜로 대체 ).

이것은 dd(일)뿐만 아니라 모든 날짜 부분 ( 여기 참조)을 사용할 수 있다는 점에서 허용되는 답변과 다릅니다 .

dateadd(minute, datediff(minute, 0, GETDATE()), 0)

위의 식에서 0는 연초 (1900-01-01)의 상수 날짜입니다. 초 또는 밀리 초와 같이 작은 부품으로 잘라야하는 경우 오버플로를 피하기 위해 잘리는 날짜에 가까운 일정한 날짜를 가져와야합니다.


1
이것은 정말 도움이되었습니다. 나는 하루 종일보다 낮은 장소에서 날짜 시간을 자르는 방법을 온통 살펴 보았습니다.
마이클-클레이는 어

1
@Michael, 의견을 보내 주셔서 감사합니다.
Lucero

1
+1 여기에는 더 많은 투표가 있어야합니다. 선택한 답변으로 확장되는 훌륭한 답변입니다.
jtate

1
인터넷에서 알 수 있듯이 전체 날짜 부분으로 제한 할 필요는 없습니다. : 여기로 15 분 간격에 대한 예는 정수 나누기 사용이다dateadd(minute, datediff(minute, 0, GETDATE()) / 15 * 15, 0)
마이클 - 어디의 클레이 셔키

7

웹에서 찾은 스 니펫은 다음과 같습니다.

 dateadd(dd,0, datediff(dd,0, YOURDATE))
 e.g.
 dateadd(dd,0, datediff(dd,0, getDate()))

나는 2005에 있지만 2008에 대한 새로운 기능이 있다고 생각 했습니까 ??
KM.

2
산뜻한! 나는 날짜 부분을 나누고 문자열 처리를 사용하여 다시 묶는 것에 의지했을 것입니다. 관련성이 없지만 SQL2008에는 시간 요소가없는 순수한 날짜 전용 데이터 형식이 있습니다.
Frans

1
그리고 DateAdd 피연산자가 섞여 DateAdd(dd, DateDiff(...), 0)있습니다. 조심하지 않으면 물릴 수 있습니다.
ErikE

1

SQl 2005에서는 trunc_date 함수를 다음과 같이 작성할 수 있습니다.

(1)

CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
    CAST(FLOOR( CAST( @date AS FLOAT ) )AS DATETIME)
END

첫 번째 방법은 훨씬 더 깨끗합니다. 최종 CAST ()를 포함하여 3 개의 메소드 호출 만 사용하며 자동 연결 인 문자열 연결을 수행하지 않습니다. 또한 여기에는 거대한 캐스트가 없습니다. 날짜 / 시간 스탬프를 표현할 수 있다고 생각되면 날짜에서 숫자로, 다시 날짜로 변환하는 것은 매우 쉬운 과정입니다.

(2)

CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
      SELECT CONVERT(varchar, @date,112)
END

Microsoft의 datetimes 구현 (2) 또는 (3)에 대해 우려되는 경우 괜찮을 수 있습니다.

(삼)

CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
SELECT CAST((STR( YEAR( @date ) ) + '/' +STR( MONTH( @date ) ) + '/' +STR( DAY(@date ) )
) AS DATETIME
END

셋째, 더 자세한 방법입니다. 이를 위해서는 날짜를 년, 월 및 일 부분으로 나누어 "yyyy / mm / dd"형식으로 한 다음 날짜로 다시 캐스팅해야합니다. 이 메소드에는 문자열 연결은 말할 것도없고 최종 CAST ()를 포함하여 7 개의 메소드 호출이 포함됩니다.


1
CONVERT(DATE, <yourdatetime>) or CONVERT(DATE, GetDate()) or CONVERT(DATE, CURRENT_TIMESTAMP)


0

DATETIME 필드를 하루 종일 (예 : 1 분)로 자르는 방법을 찾고있는 사용자는 다음을 사용할 수 있습니다.

SELECT CAST(FLOOR(CAST(GETDATE() AS FLOAT)) + (FLOOR((CAST(GETDATE() AS FLOAT) - FLOOR(CAST(GETDATE() AS FLOAT))) * 1440.0) + (3.0/86400000.0)) / 1440.0 AS DATETIME)

오늘이 2010-11-26 14:54:43.123그렇다면2010-11-26 14:54:00.000 입니다.

잘리는 간격을 변경하려면 1440.0을 하루의 간격 수로 바꾸십시오. 예를 들면 다음과 같습니다.

24hrs          =   24.0  (for every hour)
24hrs / 0.5hrs =   48.0  (for every half hour)
24hrs / (1/60) = 1440.0  (for every minute)

(항상 .0플로트에 내재적으로 캐스트하기 위해 끝에 끝을 놓으십시오 .)


(가) 궁금 당신의 사람들을 위해 (3.0/86400000)내 계산입니다, SQL 서버 2005에서 캐스팅하지 않는 것 FLOATDATETIME이 그것을 바닥재 전에 3 밀리 초를 추가하므로, 정확하게.


1
그러나 부동 소수점 정밀도 제한으로 인해 반올림 오류에주의하십시오. 또한 datetime2데이터 유형 에서는 작동하지 않습니다 .
Lucero

시간의 경우 SELECT DATEADD (hour, DATEDIFF (hour, 0, GETDATE ()), 0)도 작동합니다. 분도 있지만 초는 오버플로가 발생합니다.
켈리 클라인

플로팅하여 날짜 시간으로 다시 캐스팅하면 제대로 작동하지 않습니다 .
ErikE

0

이 쿼리는 trunc(sysdate)Oracle 과 동등한 결과를 제공해야합니다 .

SELECT  * 
FROM    your_table
WHERE   CONVERT(varchar(12), your_column_name, 101)
      = CONVERT(varchar(12), GETDATE(), 101)

도움이 되었기를 바랍니다!


0

using Substringdatetime 변수에서 날짜 를 추출 할 수 있으며 datetime으로 다시 캐스팅하면 시간 부분이 무시됩니다.

declare @SomeDate datetime = '2009-05-28 16:30:22'
SELECT cast(substring(convert(varchar(12),@SomeDate,111),0,12) as Datetime) 

또한 datetime 변수의 일부에 액세스하여 다음과 같이 구문 잘린 날짜에 병합 할 수 있습니다.

SELECT cast(DATENAME(year, @Somedate) + '-' + 
       Convert(varchar(2),DATEPART(month, @Somedate)) + '-' +
       DATENAME(day, @Somedate) 
       as datetime)

0

신탁:

TRUNC(SYSDATE, 'MONTH')

SQL 서버 :

DATEADD(DAY, - DATEPART(DAY, DateField) + 1, DateField)

날짜에서 분 또는 시간을 자르는 데 비슷하게 사용할 수 있습니다.



당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.