SQL Server에서 날짜 시간의 일부를 제거하는 가장 좋은 방법


514

SQL Server의 날짜 / 시간 필드에서 시간 부분을 제거 할 때 가장 좋은 성능을 제공하는 방법은 무엇입니까?

a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

또는

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

두 번째 방법은 몇 가지 더 어느 쪽이든 바이트하지만 그 변환의 속도와 같은 중요하지 않을 수도 있습니다 보내 않습니다.

둘 다 매우 빠르지 만 수백 개 이상의 행을 처리 할 때 속도에 차이가있을 수 있습니까?

또한 SQL에서 datetime의 시간 부분을 제거하는 더 좋은 방법이 있습니까?


1
나는 생산 테이블 중 하나의 백만 개의 레코드에서 이것을 시도했지만 성능에 대한 정확한 독서를 얻을 수 없었습니다. 두 방법 모두 동일한 양의 데이터를 반환했습니다.
Stephen Perelson

9
18,000,000 개의 행에서 이것이 내가 찾은 것입니다 (SQL Server 2008). 방법 b는 방법 a보다 약 24 % 느립니다. CAST (FLOOR (CAST (getdate () AS FLOAT)) AS DATETIME)는 방법 a보다 3.5 % 느립니다. 방법 a는 성능면에서 승자가 된 것 같습니다. 큰 답변에 감사드립니다.
스티븐 Perelson

46
도대체 SQL에 어쨌든 내장 함수가없는 이유는 무엇입니까? !!
게리 맥길

10
SQL 2008의 새로운 DATE 데이터 유형이이를 처리합니다.
Philip Kelley

답변:


557

엄밀히 말하면, 방법 a이 가장 자원 집약적입니다.

a) select DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

너무 많은 시간을 할애하여 몇 백만 행에 걸쳐 동일한 총 지속 시간 동안 CPU 집약도가 입증되지 않았습니다. .

비슷한 결과를 가진 다른 곳에서도 비슷한 테스트를 보았습니다.

나는 DATEADD / DATEDIFF 때문에 선호 :

2011 년 10 월 편집

SQL 서버 2008+의 경우에 CAST 수 있습니다 dateCAST(getdate() AS date). 또는 date데이터 유형을 사용 하여 제거 할 시간이 없습니다.

2012 년 1 월 수정

이것이 얼마나 유연한 지에 대한 효과적인 예 : SQL Server에서 반올림 시간 또는 날짜 그림으로 계산해야 함

편집 : 2012 년 5 월호

생각없이 WHERE 절 등에서 이것을 사용하지 마십시오. 열에 함수 또는 CAST를 추가하면 인덱스 사용이 무효화됩니다. 여기 2 번을 참조하십시오 : http://www.simple-talk.com/sql/t-sql-programming/ten-common-sql-programming-mistakes/

이제 여기에는 CAST를 올바르게 관리하는 최신 SQL Server 옵티 마이저 버전의 예가 있지만 일반적으로 나쁜 생각입니다 ...

datetime2의 2018 년 9 월 편집

DECLARE @datetime2value datetime2 = '02180912 11:45' --this is deliberately within datetime2, year 0218
DECLARE @datetime2epoch datetime2 = '19000101'

select DATEADD(dd, DATEDIFF(dd, @datetime2epoch, @datetime2value), @datetime2epoch)

3
@David Sopko 2011 년 10 월 편집 코드는 다음과 같습니다. select cast (GETDATE () 날짜)
Choco Smith

1
최신 버전의 SQL의 경우 datetime 대신 date를 사용하면 시간을 처리 할 필요가 없습니다. 다음 샘플을 사용하십시오. 선언 noTime 날짜 = getdate (), withTime 날짜 시간 = getdate () select @ noTime, @ withTime
ozkary

1
날짜 만 있으면 캐스트 날짜가 좋습니다. 그러나 종종 자정에 현재 날짜가 필요하므로 추가 날짜 조작을 수행 할 수 있습니다. DATE데이터 시간은 당신이 다른 날짜 / 시간 데이터 형식 DATEADD, DATEDIFF 같은 것들에 관계 및 상호 작용으로 할 수있게된다 무슨 불쾌 제한적입니다. 그러한 경우 DATEADD()접근 방식이 왕이됩니다.
Xedni

모든 날짜에 적용되는 것은 아닙니다. 연도 가 0218아닌 실수로 입력 한 경우 귀하의 진술 부분에서 예외가 발생합니다. 시도 :2018DATEDIFFThe conversion of a datetime2 data type to a datetime data type resulted in an out-of-range datetime valueselect DATEDIFF(dd, 0, convert(datetime2(0), '0218-09-12', 120))
Bernhard Döbler

1
내가 대답했을 때 2009 년 7 월에 @ BernhardDöbler는 "0218"이 유효한 날짜 였으므로 아직까지는 얻지 못했을 것입니다. 또한 "0"은 datetime2의 경우 19000101로 변환되지 않습니다. 이 선택 해보십시오SELECT DATEDIFF(dd, '19000101', convert(datetime2(0), '0218-09-12', 120))
gbn

69

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

CONVERT(DATE, getdate(), 101)

13
세 번째 인수는 a에서 a datetime로 변환 할 때 결과에 ​​전혀 영향을 미치지 date않으므로 솔루션은 효과적으로 CONVERT(DATE,getdate())한 번 이상 제안되었습니다.
Andriy M

내가 쓸모 없다고 생각하는 CAST(GETDATE() AS DATE)ANSI 만 사용하십시오 CAST(CURRENT_TIMESTAMP AS DATE). 첫 번째를 유지하십시오.
Ivanzinho

52

물론 이것은 오래된 스레드이지만 완료되도록합니다.

SQL 2008부터는 DATE 데이터 유형을 사용하여 간단하게 수행 할 수 있습니다.

SELECT CONVERT(DATE,GETDATE())

21
SELECT CAST(FLOOR(CAST(getdate() AS FLOAT)) AS DATETIME)

... 아니 아래 의견에 따르면 좋은 해결책 .

나는이 답변을 삭제하지만, 여기에 반대 의견으로 남겨 두겠습니다. 그것이 좋은 아이디어가 아닌지에 대한 논평자의 설명 이 여전히 유용하다고 생각하기 때문입니다.


GBN의 답변을 참조하십시오. 많은 사람들이 이것을 조사했습니다. DATETIME은 부동으로 저장되지 않으므로 DATEADD / DATEDIFF를 사용하면 유형간에 수학적으로 조작 할 필요가 없습니다.
MatBailie

귀하가 설명 한 이유로 DATETIME에서 FLOAT 로의 캐스트를 피하고 싶을 수도 있지만 OP의 옵션 (a)에서 0에서 암시 적으로 변환되지 않는 것도 문제입니까? 흠 ... 나는이 경우 FLOAT가 아니며 서버가 아마도 시간 정보를 버릴만큼 똑똑하다고 생각합니다. 좋아, 나는 인정한다 :-)
Gary McGill

0은 실제로 숫자 유형 (INT가 추측 할 것입니다)에서 DATETIME으로의 암시 적 변환입니다. 그러나 상수 표현식이기 때문에 옵티마이 저는 컴파일시 저장 프로 시저에 대해이를 수행 할 수 있으며 SQL을 동적으로 실행하기 위해 한 번만 수행하면됩니다. 즉, FLOAT 기반 쿼리에는 모든 행에 대해 동등한 오버 헤드가 있습니다.
MatBailie

플로팅 캐스팅은 매우 정확하지 않습니다. 이 답변은 삭제해야합니다. 아무도이 코드를 사용해서는 안됩니다.
usr

3
플로팅 후 날짜 시간으로 되돌아가는 것이 안전하지 않다는 것은 말할 것도없고 플로트의 정밀도는 충분하지 않습니다. 따라서 나는 전혀 추천 할 수 없다고 생각합니다. 자세한 내용은이 게시물을 참조하십시오 .
ErikE

17

SQL Server 2008에는 DATE 날짜 유형 (TIME 데이터 유형)이 있습니다.

CAST(GetDate() as DATE)

또는

declare @Dt as DATE = GetDate()

이것이 내가 사용한 것이고 잘 작동했습니다. 가장 간단한 답변 인 것 같습니다. CONVERT와 함께 사용하면 어떤 단점이 있습니까?
joelmdev

1
CAST와 CONVERT는 기능면에서 동일합니다. 차이점은 CAST는 ANSI 표준의 일부이고 CONVERT는 T-SQL에만 해당한다는 점입니다. 따라서 가능하면 CAST를 사용하십시오.
troy

@troy 3 개의 타이핑 문자를 저장할 수 있고 구문이 CONVERT보다 명확하기 때문에 CAST를 사용합니다. ANSI 표준 부분은 쓸모가 없습니다
Ivanzinho

8

또 다른 중복 질문의 또 다른 답변이 있습니다.

SELECT CAST(CAST(getutcdate() - 0.50000004 AS int) AS datetime) 

이 매직 넘버 방식은 DATEADD 방식보다 약간 빠릅니다. (~ 10 % 인 것 같습니다)

수백만 레코드의 CPU 시간 :

DATEADD   MAGIC FLOAT
500       453
453       360
375       375
406       360

그러나이 숫자는 이미 매우 빠르기 때문에 관련이 없을 수 있습니다. 레코드 세트가 100,000 이상이 아니라면 CPU 시간을 0 이상으로 읽을 수 없었습니다.

DateAdd가이 목적을위한 것이며보다 강력하다는 사실을 고려하면 DateAdd를 사용한다고합니다.


1
끔찍하다. 이런 식으로 데이터를 위험에 빠뜨리지 않았습니다. 테스트 한 날짜뿐만 아니라 모든 날짜 시간에 이것이 올바른지 누가 알 수 있습니까?
usr

@usr 아, 맞습니다. 단지 마법의 숫자 일 뿐이므로 그런 이유로 사용해서는 안됩니다. 정확성을 확인하려면 하루에 가능한 모든 날짜를 표에 넣고 결과를 확인하십시오! 또한 이 게시물 참조 자세한 내용입니다.
ErikE

@ErikE 좋은 지적. 귀하의 답변은 사용 '12:00:00.003'하는 것이 훨씬 낫습니다.
usr

6
SELECT CAST(CAST(GETDATE() AS DATE) AS DATETIME)

4
유효한 옵션입니다. 예. 그러나이 스레드에서 두 번 이상 제안되었습니다.
Andriy M

솔직히이 솔루션은 읽기가 가장 쉽습니다. 나의 goto
BelgoCanadian

5

나는 정말 좋아한다:

[date] = CONVERT(VARCHAR(10), GETDATE(), 120)

120형식 코드는 ISO 8601 표준에 날짜를 강요합니다 :

'YYYY-MM-DD' or '2017-01-09'

dplyr ( R) 및 팬더 ( Python) 에서 사용하기 매우 쉽습니다 !


3

조심해!

방법 a)와 b)가 항상 동일한 출력을 갖는 것은 아닙니다!

select DATEADD(dd, DATEDIFF(dd, 0, '2013-12-31 23:59:59.999'), 0)

산출: 2014-01-01 00:00:00.000

select cast(convert(char(11), '2013-12-31 23:59:59.999', 113) as datetime)

산출: 2013-12-31 00:00:00.000

(MS SQL Server 2005 및 2008 R2에서 테스트)

편집 : Adam의 의견에 따르면 테이블에서 날짜 값을 읽으면이 문제가 발생하지 않지만 날짜 값을 리터럴로 제공하면 발생할 수 있습니다 (예 : ADO.NET을 통해 호출 된 저장 프로 시저의 매개 변수로).


1
.999는 SQL Server의 DATETIME열에 저장할 수 없습니다 . 가장 높은 값 은 .997입니다. msdn.microsoft.com/en-us/library/ms187819.aspx 에서 값이 천 위로 0, 3 또는 7로 반올림됨을 알 수 있습니다. OP에는 표시되지 않습니다. 표에서 테스트의 가치.
Adam Wenger

당신이 올바른지. 나는 이것을 OP 질문에 대한 답변으로 게시하는 것을 의미하지는 않았지만 다른 사람들이 볼 수있는 의견으로 게시했지만 11 개의 평판 만 가지고 있었고 의견을 제출하는 데 15가 필요했습니다.
broslav

첫 번째 스 니펫에서 문자열 상수는 암시 적으로 날짜 시간으로 변환되고 두 번째 스 니펫에서는 문자열로 유지됩니다 (113은 무시됩니다).
Andriy M

2

처음부터 인서트 / 업데이트시 스트립 타임. 즉석 변환의 경우 사용자 정의 기능을 유지 관리 측면에서 능가 할 수있는 것은 없습니다.

select date_only(dd)

구현은 date_only원하는 것이 될 수 있습니다. 이제 추상화되어 호출 코드가 훨씬 깔끔합니다.


한 번 선택한 열에서 시간을 제거하는 트리거를 고안했습니다. 데이터가 나쁘지 않으면 정리할 필요가 없습니다.
Philip Kelley

2
UDF 방식에는 단점이 있지만 SARGable은 아닙니다. JOIN 또는 WHERE 절에 사용되면 옵티마이 저는 성능을 향상시키기 위해 INDEX를 사용할 수 없습니다. 그러나 DATEADD / DATEDIFF 접근 방식을 사용하는 것은 SARGable이며 INDEX의 혜택을 누릴 수 있습니다. (분명히 FLOAT 방법도 SARGable입니다)
MatBailie

1
@MatBailie 나는달라고 구걸한다! UDF는 확실히 SARGable이 아니지만 Dateadd 나 Float to Float도 아닙니다! WHERE DateAdd(DateDiff(Column)) = @DateValue인덱스를 사용하지 않습니다. 반면에, WHERE Column >= dbo.UDF(@DateValue) AND Column < dbo.UDF(@DateValue + 1) 이다 스 SARGable. 어떻게 넣었는지주의하십시오.
ErikE

2

이 질문을 참조하십시오 :
SQL Server에서 날짜 시간을 자르려면 어떻게해야합니까?

무엇을하든 문자열 방법을 사용하지 마십시오 . 그것은 당신이 할 수있는 최악의 방법에 관한 것입니다.


고마워, 나는 이것이 이전에 요청되어야한다고 생각했다. 이상한 점은 SQL Server 2008에서 float 메서드가 dateadd (dd, 0, datediff (dd, 0, getDate ())) 메서드보다 실제로 3.5 % 느리다는 점을 발견했습니다. 각 방법에 대해 여러 번 테스트를 실행했으며 당시 데이터베이스 서버는 다른 용도로 사용되지 않았습니다.
Stephen Perelson

벤치마킹을 업무의 일부로 매우 과학적으로 정기적으로 수행한다는 것을 보여주지 않은 사람은 벤치마킹에 회의적이라고 가정 해 봅시다. gbn의 링크에서 Thomas의 벤치 마크조차도 볼 때 몇 가지 명백한 문제가 있습니다. 그것이 반드시 틀린 것은 아니며 단지 결정적인 것은 아닙니다. 캐스트 / 플로어 / 캐스트 방법은 매우 오랫동안 가장 빠른 방법으로 받아 들여졌으며 한 번은 틀림없이 사실이라고 생각합니다. 즉, 나는 그것을 재고하기 시작했다. 특히 SQL Server 2008의 경우 어쨌든 완전히 필요하지 않습니다.
Joel Coehoorn

1
문자열 방법은 사용, 읽기 및 기억이 매우 쉽습니다. 그것들은 당신이 과소 평가하고 있다고 생각하는 매우 중요한 요소입니다!
Ben

1
@JoelCoehoorn, 변환 스타일 121을 "ODBC Canonical"이라고합니다. 데이터 정렬 또는 로캘에 따라 다릅니다. 문자열 트릭은 연도, 연도, 월, 일,시 또는 분으로 일반화하기도 쉽습니다.
Ben

1
@Ben 문자열 트릭은 개발자에게 문자열 변환을 사용하도록 지시합니다. 그것들은 효과 가 있지만 날짜 계산은 여러 가지 이유로 훨씬 우수합니다. 최소한 속도는 아니지만 더 많은 숫자로 날짜를 사용하여 학습하는 것이 개발자와 그의 정신 능력에 미치는 영향 코드에서 숫자 조작으로 유동적이어야합니다.
ErikE

2

이미 대답했지만 잘못도 버릴 것입니다 ... 이것은 또한 잘 수행되지만 플로트에서 소수 (시간을 저장하는)를 버리고 전체 부분 (날짜) 만 반환하여 작동합니다

 CAST(
FLOOR( CAST( GETDATE() AS FLOAT ) )
AS DATETIME
)

두 번째 로이 솔루션을 찾았습니다 ... 이 코드를 가져 왔습니다


1
float 변환하는 것은 안전하지 않습니다 .
ErikE

2
CAST(round(cast(getdate()as real),0,1) AS datetime)

이 방법은 문자열 함수를 사용하지 않습니다. Date기본적으로 십진수 앞에 숫자가 하루의 일부인 실제 데이터 유형입니다.

이것은 많은 것보다 빠를 것 같아요.


1
플로트 캐스팅하는 것은 안전하지 않습니다 .
ErikE


2

CONVERT (char (10), GetDate (), 126)를 선택하십시오.


@broslav의 답변에 언급 된 방법이 나이 스레드 에서 가장 느리게 결정 된 방법 (허용 된 답변과 동일한 링크)과 제안의 주요 차이점은 무엇입니까 ?
Andriy M

1

내 생각 엔 cast(floor(cast(getdate()as float))as datetime)

real은 32 비트이므로 일부 정보가 손실 될 수 있습니다.

이것은 가장 빠릅니다 cast(cast(getdate()+x-0.5 as int)as datetime)

... 약 10 % 더 빠름(about 0.49 microseconds CPU vs. 0.58)

이것은 권장되었으며 지금 테스트에서 같은 시간이 걸립니다. DATEADD(dd, DATEDIFF(dd, 0, getdate()), 0)

SQL 2008에서 SQL CLR 함수는 SQL 함수를 사용하는 것보다 1.35 마이크로 초에서 6.5 마이크로 섹션보다 약 5 배 더 빠르므로 간단한 SQL UDF에 비해 SQL CLR 함수의 함수 호출 오버 헤드가 훨씬 낮습니다.

SQL 2005에서 SQL CLR 기능은 테스트 당이 느린 기능에 비해 16 배 더 빠릅니다.

create function dateonly (  @dt datetime )
returns datetime
as
begin
return cast(floor(cast(@dt as float))as int)
end

1

어때요 select cast(cast my_datetime_field as date) as datetime)? 이로 인해 시간이 00:00으로 설정된 동일한 날짜가 발생하지만 텍스트로의 변환을 피하고 명시적인 숫자 반올림을 피할 수 있습니다.



그들은 동일하지 않습니다. 다른 답변은 시간 구성 요소가없는 날짜 캐스팅하여 제안했습니다 . 내 게시물은 자정 시간과 날짜 시간으로 설정합니다. 큰 차이가 있습니다. MS Excel로 내 보내면 날짜 시간보다 날짜 시간이 훨씬 잘 처리됩니다.
Dr. Drew

첫 번째는 정확히 같습니다.
Mikael Eriksson

알았어요 필요한 경우 답변을 중복으로 제거해 드리겠습니다.
Dr. Drew

1

나는 당신 TSQL이 그것을 엄격하게 고수한다면 이것이 시간을 자르는 가장 빠른 방법 이라고 생각합니다 .

 select convert(datetime,convert(int,convert(float,[Modified])))

이 절단 방법이 방법보다 약 5 % 빠릅니다 DateAdd. 그리고 이것은 다음과 같이 가장 가까운 날로 반올림하도록 쉽게 수정할 수 있습니다.

select convert(datetime,ROUND(convert(float,[Modified]),0))


1

여기에서는 SQL Server의 날짜 시간 일부를 제거하는 기능을 만들었습니다. 용법:

  • 첫 번째 매개 변수는 제거 할 날짜 시간입니다.
  • 두 번째 매개 변수는 문자입니다.
    • s : 초로 반올림; 밀리 초를 제거합니다
    • m : 분으로 반올림; 초와 밀리 초를 제거합니다
    • h : 시간으로 반올림; 분, 초 및 밀리 초를 제거합니다.
    • d : 일로 반올림; 시간, 분, 초 및 밀리 초를 제거합니다.
  • 새로운 날짜 시간을 반환

create function dbo.uf_RoundDateTime(@dt as datetime, @part as char) returns datetime as begin if CHARINDEX( @part, 'smhd',0) = 0 return @dt; return cast( Case @part when 's' then convert(varchar(19), @dt, 126) when 'm' then convert(varchar(17), @dt, 126) + '00' when 'h' then convert(varchar(14), @dt, 126) + '00:00' when 'd' then convert(varchar(14), @dt, 112) end as datetime ) end


고마워 안드리! 나는 나의 추천이 그렇게 효율적이지 않다는 것을 몰랐다. 적어도 그것은 작동하지만 당신은 옳습니다.
Max Vargas

1

위의 여러 버전이 작동하지 않아서 누군가 Sybase 버전을 찾고있는 경우를 대비하여

CAST(CONVERT(DATE,GETDATE(),103) AS DATETIME)
  • Adaptive Server 15.7에서 실행되는 I SQL v11에서 테스트

허용되는 답변을 편집하는 것이 더 적합합니다. 20 개의 다른 답변으로 이것은 묻히고 거의 찾을 수 없습니다. 또한 허용 응답 차종이 사용하는 언급 cast: SQL 서버 2008+, 당신은 지금까지 CAST 수 있습니다하십시오. 또는 날짜를 사용하여 제거 할 시간이 없습니다.
EWit

이것을 동등한 Sybase 질문에 대한 답변으로 게시하는 것이 가장 좋습니다. 그러한 질문이 없으면 자유롭게 질문을 작성하여 직접 답변하십시오.
Andriy M

게다가, 당신이 변환 할 때 변환하는 세 번째 매개 변수를 지정하는 의미가 없습니다 datetimedate: 둘 다 사람들의 고유 한 형식이 있습니다.
Andriy M

0

가능한 경우, 이와 같은 특별한 경우 CLR 기능을 사용하고 싶습니다.

이 경우 :

[Microsoft.SqlServer.Server.SqlFunction]
    public static SqlDateTime DateOnly(SqlDateTime input)
    {
        if (!input.IsNull)
        {
            SqlDateTime dt = new SqlDateTime(input.Value.Year, input.Value.Month, input.Value.Day, 0, 0, 0);

            return dt;
        }
        else
            return SqlDateTime.Null;
    }

0

나는 개인적으로 거의 항상 사용자 정의 함수를 사용 합니다 으로 SQL Server 2005 (또는 그 이하 버전)를 처리하는 경우 를 하지만 UDF를 사용하는 경우 특히 WHERE 절에 적용 할 경우 특히 단점이 있습니다 (아래 및 자세한 내용은이 답변에 대한 의견). SQL Server 2008 이상을 사용하는 경우-아래를 참조하십시오.

실제로, 내가 만든 대부분의 데이터베이스에 대해,이 UDF를 시작 근처에 바로 추가 할 수 있습니다. 99 %의 확률로 조만간 필요할 것입니다.

"날짜 만"및 "시간 만"에 대해 하나를 작성합니다 ( "날짜 만"하나가 둘 중 가장 많이 사용되지만).

다음은 다양한 날짜 관련 UDF에 대한 링크입니다.

필수 SQL Server 날짜, 시간 및 날짜 시간 함수
날짜 만 함수 가져 오기

마지막 링크는 날짜를 날짜 시간 필드의 일부로 가져 오는 3 가지 다른 방법을 보여 주며 각 접근 방식의 장단점을 언급합니다.

UDF를 사용하는 경우 쿼리에서 WHERE 절의 일부로 UDF를 사용하지 않도록해야하므로 쿼리 성능이 크게 저하됩니다. 주된 이유는 WHERE 절에서 UDF를 사용하면 해당 절이 비파괴 형 으로 렌더링되기 때문입니다. 하지 않기 때문에 SQL Server가 더 이상 쿼리 실행 속도를 향상시키기 위해 해당 절에 인덱스를 사용할 수 없다는 것입니다. 필자의 UDF 사용법과 관련하여 WHERE 절에서 "원시"날짜 열을 자주 사용하지만 UDF를 SELECTed 열에 적용합니다. 이러한 방식으로 UDF는 필터링 된 결과 세트에만 적용되며 필터의 일부로 테이블의 모든 행이 아닙니다.

물론 SQL Server 데이터베이스 엔진이 기본적으로 개별 날짜 및 시간 구성 요소를 제공하고이를 독립적으로 쿼리 할 수 있으므로 SQL Server 2008 이상을 사용하고 날짜와 시간을 구분하는 것이 최선의 방법입니다. 복합 날짜 시간 유형에서 날짜 또는 시간 부분을 추출하기 위해 UDF 또는 기타 메커니즘이 필요하지 않습니다.


매개 변수를 스크러빙 할 때와 같이 일부 상황에서는 UDF를 사용하는 것이 좋습니다. 그러나 대부분의 상황에서 그것은이다 끔찍한 솔루션 - 단지에 대한 방법입니다 각 행에 대해 일단 UDF를 실행 죽일 쿼리의 성능을 그것에 대한 필요없이!
ErikE

@ErikE-동의하지 않습니다. Erik, UDF는 성능을 저하시키는 요인이므로 SQL Server 2008 이상을 사용할 수 있고 내장 데이터 유형을 사용하면 이것이 최선의 해결책이 될 것입니다. (필요한 것을 달성하고 성능 측면에서). 기본적으로이 기능을 지원하지 않는 이전 버전의 SQL Server를 사용하고 있다면 요구 사항을 달성하기 위해 무언가 를 포기 해야합니다.
CraigTP

진실. 데이터베이스 엔진이 SARGable이지만 표현하기 쉬운 것을 우리에게 제공한다면 좋을 것입니다. 그 동안 하루 종일 언제라도 값을 찾고 있다면 이것이 여전히 최고의 솔루션입니다 (최소한 이전 버전의 SQL) : WHERE DateColumn >= {TimeTruncatingExpression}(@DateValue) AND DateColumn < {TimeTruncatingExpression}(@DateValue + 1). "거의 항상 UDF를 사용합니다."라는 단점이없고 날짜 전용 쿼리 SARGable을 만드는 방법을 설명하지 않았다고 말한 이후로 나는 무언가를 말해야한다고 느꼈습니다.
ErikE

@ErikE-걱정하지 마세요, Erik. UDF를 사용했을 때 성능이 가장 중요하지 않은 작은 데이터 세트로 작업했거나 "생성"날짜 필드에 대해 쿼리를 필터링했을 가능성이 있지만 열을 선택했습니다. UDF가 적용된 상태에서 이들은 일반적으로 한 번 필터링 된 작은 데이터 세트이므로이 적은 수의 레코드에 대해 UDF를 실행하는 것은 성능이 저하되지 않습니다. 즉, 당신은 매우 좋은 지적을 제기하고 이것을 반영하기 위해 내 대답을 업데이트했습니다.
CraigTP

-4

나는 사용할 것이다 :

CAST
(
CAST(YEAR(DATEFIELD) as varchar(4)) + '/' CAST(MM(DATEFIELD) as varchar(2)) + '/' CAST(DD(DATEFIELD) as varchar(2)) as datetime
) 

따라서 이미 가지고있는 날짜 필드에서 새 필드를 효과적으로 만듭니다.


2
왜 그렇게 하시겠습니까? datetime값 에서 비트를 추출 하여 문자열로 변환하고,이를 함께 연결 한 다음 결과를 다시 변환하는 datetime것이 원본 datetime( DATEADD/ DATEDIFF방법) 에 대한 직접 계산을 수행하는 것보다 낫다고 생각 하십니까?
Andriy M

또한, 무엇 MMDD? SQL Server에는 이러한 기능이 없습니다.
Andriy M
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.