programing

날짜/시간 값(SQL Server)의 시간 부분을 제거하려면 어떻게 해야 합니다.

instargram 2023. 4. 17. 21:17
반응형

날짜/시간 값(SQL Server)의 시간 부분을 제거하려면 어떻게 해야 합니다.

사용법은 다음과 같습니다.

SELECT CAST(FLOOR(CAST(getdate() as FLOAT)) as DATETIME)

더 나은, 더 우아한 방법이 있을 것 같아요.

요건:

  • 가능한 한 빨리 해야 합니다(주조가 적을수록 좋습니다).
  • 는 A가 .datetime활자

SQL Server 2008 이후

에서는 물론 은 SQL Server 2008입니다.Convert(date, @date)이 값은 다음 주소로 캐스트할 수 있습니다.datetime ★★★★★★★★★★★★★★★★★」datetime2필요하면.

SQL Server 2005 이전 버전에서는 무엇이 가장 좋은가?

SQL Server에서 날짜부터 시간을 단축하는 데 가장 빠른 방법이 무엇인지에 대한 일관되지 않은 주장을 봐왔고, 테스트를 했다고 말하는 사람도 있었지만, 제 경험은 달랐습니다.그래서 좀 더 엄격한 테스트를 하고, 내가 실수를 해도 다른 사람들이 나를 고칠 수 있도록 모든 사람들에게 대본을 전달하자.

부동 변환이 정확하지 않음

저는 하는 것을 입니다.datetime로로 합니다.float올바르게 변환되지 않기 때문입니다.시간 단축을 정확하게 하면 안 될 수도 있지만, 이것은 개발자에게 안전한 작업이고 안전하지 않다는 것을 암시적으로 전달하기 때문에 사용하는 것은 좋지 않다고 생각합니다.다음 항목을 참조하십시오.

declare @d datetime;
set @d = '2010-09-12 00:00:00.003';
select Convert(datetime, Convert(float, @d));
-- result: 2010-09-12 00:00:00.000 -- oops

이것은 우리의 코드나 온라인 예시로 사람들에게 가르쳐서는 안 되는 것입니다.

또한, 그것은 가장 빠른 길도 아니에요!

실증 – 퍼포먼스 테스트

여러 메서드가 실제로 어떻게 스택되는지 직접 테스트하려면 테스트를 더 아래로 실행하려면 다음 셋업 스크립트가 필요합니다.

create table AllDay (Tm datetime NOT NULL CONSTRAINT PK_AllDay PRIMARY KEY CLUSTERED);
declare @d datetime;
set @d = DateDiff(Day, 0, GetDate());
insert AllDay select @d;
while @@ROWCOUNT != 0
   insert AllDay
   select * from (
      select Tm =
         DateAdd(ms, (select Max(DateDiff(ms, @d, Tm)) from AllDay) + 3, Tm)
      from AllDay
   ) X
   where Tm < DateAdd(Day, 1, @d);
exec sp_spaceused AllDay;  -- 25,920,000 rows

그러면 데이터베이스에 427.57MB 테이블이 생성되며 실행하는 데 약 15~30분이 소요됩니다.데이터베이스가 작아서 10% 확장으로 설정되어 있는 경우, 처음에 충분히 큰 사이즈를 설정하는 경우보다 시간이 더 오래 걸립니다.

이제 실제 성능 테스트 스크립트를 살펴보겠습니다.2600만 행에서는 엄청난 비용이 들고 메서드 간의 성능 차이가 숨겨지기 때문에 클라이언트에 행을 반환하지 않는 것이 목적이라는 점에 유의하시기 바랍니다.

퍼포먼스 결과

set statistics time on;
-- (All queries are the same on io: logical reads 54712)
GO
declare
    @dd date,
    @d datetime,
    @di int,
    @df float,
    @dv varchar(10);

-- Round trip back to datetime
select @d = CONVERT(date, Tm) from AllDay; -- CPU time = 21234 ms,  elapsed time = 22301 ms.
select @d = CAST(Tm - 0.50000004 AS int) from AllDay; -- CPU = 23031 ms, elapsed = 24091 ms.
select @d = DATEDIFF(DAY, 0, Tm) from AllDay; -- CPU = 23782 ms, elapsed = 24818 ms.
select @d = FLOOR(CAST(Tm as float)) from AllDay; -- CPU = 36891 ms, elapsed = 38414 ms.
select @d = CONVERT(VARCHAR(8), Tm, 112) from AllDay; -- CPU = 102984 ms, elapsed = 109897 ms.
select @d = CONVERT(CHAR(8), Tm, 112) from AllDay; -- CPU = 103390 ms,  elapsed = 108236 ms.
select @d = CONVERT(VARCHAR(10), Tm, 101) from AllDay; -- CPU = 123375 ms, elapsed = 135179 ms.

-- Only to another type but not back
select @dd = Tm from AllDay; -- CPU time = 19891 ms,  elapsed time = 20937 ms.
select @di = CAST(Tm - 0.50000004 AS int) from AllDay; -- CPU = 21453 ms, elapsed = 23079 ms.
select @di = DATEDIFF(DAY, 0, Tm) from AllDay; -- CPU = 23218 ms, elapsed = 24700 ms
select @df = FLOOR(CAST(Tm as float)) from AllDay; -- CPU = 29312 ms, elapsed = 31101 ms.
select @dv = CONVERT(VARCHAR(8), Tm, 112) from AllDay; -- CPU = 64016 ms, elapsed = 67815 ms.
select @dv = CONVERT(CHAR(8), Tm, 112) from AllDay; -- CPU = 64297 ms,  elapsed = 67987 ms.
select @dv = CONVERT(VARCHAR(10), Tm, 101) from AllDay; -- CPU = 65609 ms, elapsed = 68173 ms.
GO
set statistics time off;

몇 가지 횡설수설한 분석

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ GROUP BY로 datetime따라서 디스플레이에 최종값이 필요하지 않는 한 이를 회피함으로써 CPU를 절약할 수고를 덜 수 있습니다.변환되지 않은 값을 기준으로 그룹화하여 SELECT 절에만 변환을 넣을 수도 있습니다.

select Convert(datetime, DateDiff(dd, 0, Tm))
from (select '2010-09-12 00:00:00.003') X (Tm)
group by DateDiff(dd, 0, Tm)

수치 에서는, 「 」 「 」 「 」 「 」 「 」 「 」 로의 더 에 대해서도 합니다.datetime ,는varchar산배2번?그러면 쿼리에서 날짜 계산에 할당된 CPU의 부분이 표시됩니다.CPU 사용률에는 날짜 계산이 포함되지 않은 부분이 있으며, 위의 쿼리에서 이는 19875ms에 가까운 것으로 보입니다.그러면 변환에 약간의 추가 금액이 소요되므로 변환이 두 개일 경우 그 금액이 약 두 배 정도 소모됩니다.

더 조사해 보면, to to to to와 해서 알 수 .Convert(, 112) , . . . . . . . .Convert(, 101)에는 CPU이 약간 더 긴 CPU를 사용하기 에).varchar 두 번째 이 있기 입니다.date 듭니다.varchar ,에서는Convert(, 112)CPU의 2개입니다.

위의 분석에 사용한 CPU 시간의 계산은 다음과 같습니다.

     method   round  single   base
-----------  ------  ------  -----
       date   21324   19891  18458
        int   23031   21453  19875
   datediff   23782   23218  22654
      float   36891   29312  21733
varchar-112  102984   64016  25048
varchar-101  123375   65609   7843
  • round는 로의 왕복에 필요한 CPU 시간입니다.datetime.

  • single은 대체 데이터 유형(시간 부분을 삭제하는 부작용이 있는 데이터 유형)으로 단일 변환하기 위한 CPU 시간입니다.

  • base는 뺄셈 계산입니다.single: " " " "single - (round - single) 타입과 그 데이터 datetime어느 방향에서도 거의 동일합니다.이 가정은 완벽하지는 않지만 하나의 예외만 제외하고 모두 2만 ms에 가깝기 때문에 가까운 것으로 보입니다.

가지 더 로운 점은 이 단일 입니다.Convert(date)가 메서드의 첫할 수 있기 비용이어야 ).datetimedata type)를 지정합니다.

결론

, 의 「」, 「」는,varchar은 약되며 단방향 변환은 1.8μs가 됩니다.DateDiff0.18μs로 하다이것은, 합계 18458 ms의 테스트로 25,920,000 행에 대해 가장 보수적인 「기본 CPU」시간에 근거하고 있습니다.23218 ms / 25920000 = 0.18 μs입니다.겉으로 보기에 10배 향상된 기능은 많은 것처럼 보이지만, 솔직히 수십만 개의 행(617k 행 = 1초 절감)을 처리하기 전까지는 매우 작습니다.

이 작은 절대적인 개선에도 불구하고, 제 생각에는,DateAdd퍼포먼스와 명확성의 최적의 조합이기 때문에 방법이 유리합니다.'매직 넘버'가 필요한 답변은0.50000004언젠가 누군가를 물게 될까? (5개의 0, 6개의 0)더 이해하기 어렵습니다.

기타 주의사항

시간이 나면 갈아입을 거야0.50000004로.'12:00:00.003'어떻게 되는지 보세요.같은 것으로 변환됩니다.datetime기억하기 쉽다는 것을 알게 되었습니다.

관심 있는 사용자에게는 위의 테스트가 서버에서 실행되었으며 @@Version은 다음을 반환합니다.

Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (인텔 X86) 2008년7월 9일 14:43:34 Windows NT 5.2에서의 저작권 (c) 1988-2008 Microsoft Corporation Standard Edition (빌드 3790: Service Pack 2)

SQL Server 2008에는 새로운 날짜 데이터 유형이 추가되어 이 문제가 다음과 같이 단순화되었습니다.

SELECT CAST(CAST(GETDATE() AS date) AS datetime)

DATETIME Calculations, Part 1(SQL Server Magazine, 2007년 2월)의 Itzik Ben-Gan에서는 이러한 변환을 실행하는 세 가지 방법(가장 느린 방법에서 가장 빠른 방법, 두 번째 방법과 세 번째 방법의 차이는 작음)을 보여 줍니다.

SELECT CAST(CONVERT(char(8), GETDATE(), 112) AS datetime)

SELECT DATEADD(day, DATEDIFF(day, 0, GETDATE()), 0)

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

당신의 기술(떠다니는 주조)은 잡지의 4월호에 독자가 제안했습니다.그에 따르면, 그것은 위에서 제시한 두 번째 기술에 버금가는 성능을 가지고 있다.

당신의.CAST-FLOOR-CAST적어도 MS SQL Server 2005에서는 이미 최적의 방법인 것 같습니다.

제가 본 다른 솔루션에는 문자열 변환 기능이 있습니다.Select Convert(varchar(11), getdate(),101)10배 느립니다.

시험해 보세요:

SELECT CONVERT(VARCHAR(10),[YOUR COLUMN NAME],105) [YOURTABLENAME]

SQL 2005: 날짜 추가 대신 캐스팅을 권장합니다.예를들면,

select cast(DATEDIFF(DAY, 0, datetimefield) as datetime)

데이터셋 속도가 평균 약 10% 빨라졌습니다.

select DATEADD(DAY, DATEDIFF(DAY, 0, datetimefield), 0)

(그리고 smaldatime에 투입하는 것이 더 빨랐습니다.)

언급URL : https://stackoverflow.com/questions/2775/how-to-remove-the-time-portion-of-a-datetime-value-sql-server

반응형