source

SQL Server에서 날짜/시간을 자르는 방법은 무엇입니까?

ittop 2023. 4. 7. 21:57
반응형

SQL Server에서 날짜/시간을 자르는 방법은 무엇입니까?

SQL Server 2008에서 datetime 값(시간 및 초 삭제)을 줄이는 가장 좋은 방법은 무엇입니까?

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

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

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

이는 몇 년이 지난 후에도 자주 추가 투표가 이루어지기 때문에 최신 버전의 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)

이는 datetime 열이 8바이트 이진 값으로 저장되기 때문에 작동합니다.값을 플로트로 캐스팅하고 플로어링하여 비율을 제거합니다.이 값을 날짜/시간으로 다시 캐스팅하면 값의 시간 부분이 사라집니다.복잡한 논리 없이 그저 조금씩 옮겨가고 있고 매우 빠릅니다.

이는 Microsoft가 서비스 자동 업데이트에서도 언제든지 자유롭게 변경할 수 있는 구현 세부 사항에 의존합니다.휴대성도 별로 좋지 않습니다.실제로 이 구현이 조만간 변경될 가능성은 매우 낮지만, 이 구현을 사용하는 경우 위험을 인식하는 것이 여전히 중요합니다.그리고 이제 데이트할 수 있는 옵션이 생겼으니, 거의 필요 없어요.

잘못된 방법:

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

잘못된 방법은 문자열로 변환하고 문자열을 잘라낸 후 날짜/시간으로 다시 변환하는 것입니다.틀렸습니다.두 가지 이유로 1) 모든 로케일에서 동작하지 않을 수 있으며 2) 가장 느린 방법으로 동작할 수 있습니다.조금뿐만이 아니라 다른 옵션보다 한두 개 정도 느립니다.


업데이트 최근 몇 가지 표를 얻고 있습니다.이 글을 올린 이후 SQL Server가 "올바른" 방식과 "빠른" 방식의 성능 차이를 최적화할 것이라는 확실한 증거를 발견했습니다.즉, 이제는 전자를 선호해야 합니다.

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

대부분의 경우 데이터베이스가 이미 병목현상이 되고 있습니다.일반적으로 성능 향상을 위해 하드웨어를 추가하는 데 비용이 가장 많이 들고 이러한 추가 작업을 올바르게 수행하는 데 가장 어려운 서버입니다(예를 들어 디스크와 메모리의 균형을 유지해야 합니다).또한 기술적으로나 비즈니스 측면에서나 외부로 확장하기가 가장 어렵습니다.기술적으로는 데이터베이스 서버보다 웹 서버나 애플리케이션 서버를 추가하는 것이 훨씬 쉽습니다.또한 이것이 틀렸다고 해도 IIS나 Apache의 서버 라이센스당 $20,000 이상을 지불하지 않아도 됩니다.

요점은 가능한 한 어플리케이션 레벨에서 이 작업을 진행해야 한다는 것입니다.SQL Server에서 날짜/시간을 잘라내야 하는 유일한 시기는 날짜별로 그룹화할 필요가 있을 때이며, 이때도 추가 열을 계산 열로 설정하거나 삽입/업데이트 시 유지 관리하거나 응용 프로그램 로직으로 유지해야 합니다.이 인덱스 파괴적이고 CPU 부하가 높은 작업을 데이터베이스에서 삭제하십시오.

SQL Server 2008에만 해당

CAST(@SomeDateTime AS Date) 

그런 다음 원하는 경우 날짜/시간으로 다시 던집니다.

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

더 답변을 날짜 대체하다GETDATE()잘라낼 날짜)를 지정합니다.

만 할 수 것이 .dd(일) 단, 날짜 부분(여기를 참조):

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

에서 ""는0는 연도의 시작일(198-01-01)의 일정 날짜입니다.초 또는 밀리초와 같이 더 작은 부분으로 잘라내야 하는 경우 오버플로를 방지하려면 잘라낼 날짜에 가까운 일정한 날짜를 사용해야 합니다.

이 작업을 수행할 때 웹에서 찾은 조각은 다음과 같습니다.

 dateadd(dd,0, datediff(dd,0, YOURDATE))
 e.g.
 dateadd(dd,0, datediff(dd,0, getDate()))
CONVERT(DATE, <yourdatetime>) or CONVERT(DATE, GetDate()) or CONVERT(DATE, CURRENT_TIMESTAMP)

분석 작업을 할 때는 날짜/시간 절단이 많이 필요할 수 있습니다.이 문제를 해결하는 데 도움이 되는 작은 기능을 만들었습니다.

CREATE FUNCTION TRUNC_DATE
(
    @datetime datetime, -- datetime to be truncated
    @level VARCHAR(10)  -- truncation level: year, month, day, hour and minute
)
RETURNS DATETIME
AS
BEGIN

    IF (UPPER(@level) = 'YEAR')
       RETURN DATEADD(YEAR,   DATEDIFF(YEAR, 0, @datetime), 0)
    ELSE IF (UPPER(@level) = 'MONTH')
        RETURN DATEADD(MONTH,   DATEDIFF(MONTH, 0, @datetime), 0)
    ELSE IF(UPPER(@level) = 'DAY')
       RETURN DATEADD(DAY,   DATEDIFF(DAY, 0, @datetime), 0)
    ELSE IF (UPPER(@level) = 'HOUR')
       RETURN DATEADD(HOUR,   DATEDIFF(HOUR, 0, @datetime), 0)
    ELSE IF (UPPER(@level) = 'MINUTE')
       RETURN DATEADD(MINUTE,   DATEDIFF(MINUTE, 0, @datetime), 0)

    RETURN @datetime
END
GO

함수를 평가하려면(GETDATE() 열을 변경합니다).

SELECT DBO.TRUNC_DATE(GETDATE(), 'YEAR')   YEAR;
SELECT DBO.TRUNC_DATE(GETDATE(), 'MONTH')  YEAR_MONTH;
SELECT DBO.TRUNC_DATE(GETDATE(), 'DAY')    YEAR_MONTH_DAY;
SELECT DBO.TRUNC_DATE(GETDATE(), 'HOUR')   YEAR_MONTH_DAY_HOUR;
SELECT DBO.TRUNC_DATE(GETDATE(), 'MINUTE') YEAR_MONTH_DAY_HOUR_MINUTE;

출력:

여기에 이미지 설명 입력

SQL 2005에서는 trunk_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 의 데이터 타임(2) 또는 (3) 의 실장이 염려되는 경우는, 문제가 없습니다.

(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

세 번째, 좀 더 장황한 방법.이를 위해서는 날짜를 년, 월 및 일 부분으로 분할하여 "yyy/mm/dd" 형식으로 합친 후 날짜에 다시 캐스팅해야 합니다.이 메서드에는 문자열 연결은 말할 것도 없고 최종 CAST()를 포함한7개의 메서드콜이 포함됩니다

datetime으로 cast(float(float(cast(getdate() as float)))를 선택합니다.이것을 참조해 주세요.

DATETIME 필드를 하루 미만으로 잘라내는 방법을 찾고 계신 분(예: 매분)은 다음을 사용할 수 있습니다.

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을 1일 간격 수로 바꿉니다.다음은 예를 제시하겠습니다.

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 Server 2005는 다음에서 캐스트되지 않은 것 같습니다.FLOAT로.DATETIME플로어링하기 전에 3밀리초가 걸립니다.

이 쿼리는 다음과 같은 결과를 제공합니다.trunc(sysdate)Oracle에서.

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

이게 도움이 됐으면 좋겠네요!

날짜를 추출할 수도 있습니다.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)

Oracle:

TRUNC(SYSDATE, 'MONTH')

SQL Server:

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

마찬가지로 날짜에서 분 또는 시간을 잘라내는 데 사용할 수 있습니다.

다음과 같이 할 수 있습니다(SQL 2008).

@SomeDate date = getdate() 선언

select @SomeDate

2009-05-28

TRUNC(aDate, 'DD')는 min, sec 및 hrs를 잘라냅니다.

SRC: http://www.techonthenet.com/oracle/functions/trunc_date.php

SQL Server 2022에는 DATETRUNC가 있습니다.

DECLARE @d datetime2 = '2021-12-08 11:30:15.1234567';
SELECT 'Year', DATETRUNC(year, @d);
SELECT 'Quarter', DATETRUNC(quarter, @d);
SELECT 'Month', DATETRUNC(month, @d);
SELECT 'Week', DATETRUNC(week, @d); -- Using the default DATEFIRST setting value of 7 (U.S. English)
SELECT 'Iso_week', DATETRUNC(iso_week, @d);
SELECT 'DayOfYear', DATETRUNC(dayofyear, @d);
SELECT 'Day', DATETRUNC(day, @d);
SELECT 'Hour', DATETRUNC(hour, @d);
SELECT 'Minute', DATETRUNC(minute, @d);
SELECT 'Second', DATETRUNC(second, @d);
SELECT 'Millisecond', DATETRUNC(millisecond, @d);
SELECT 'Microsecond', DATETRUNC(microsecond, @d);
Year        2021-01-01 00:00:00.0000000
Quarter     2021-10-01 00:00:00.0000000
Month       2021-12-01 00:00:00.0000000
Week        2021-12-05 00:00:00.0000000
Iso_week    2021-12-06 00:00:00.0000000
DayOfYear   2021-12-08 00:00:00.0000000
Day         2021-12-08 00:00:00.0000000
Hour        2021-12-08 11:00:00.0000000
Minute      2021-12-08 11:30:00.0000000
Second      2021-12-08 11:30:15.0000000
Millisecond 2021-12-08 11:30:15.1230000
Microsecond 2021-12-08 11:30:15.1234560

https://learn.microsoft.com/en-us/sql/t-sql/functions/datetrunc-transact-sql?view=sql-server-ver16

언급URL : https://stackoverflow.com/questions/923295/how-can-i-truncate-a-datetime-in-sql-server

반응형