code

SQL Server에서 날짜 플로어

codestyles 2020. 11. 4. 07:59
반응형

SQL Server에서 날짜 플로어


SQL Server에서 DATETIME을 초 / 분 / 시간 / 일 / 년으로 "하향 조정"하는 방법은 무엇입니까?

날짜가 2008-09-17 12 : 56 : 53.430 인 경우 바닥재 출력은 다음과 같아야합니다.

  • 년 : 2008-01-01 00 : 00 : 00.000
  • 월 : 2008-09-01 00 : 00 : 00.000
  • 일 : 2008-09-17 00 : 00 : 00.000
  • 시간 : 2008-09-17 12 : 00 : 00.000
  • 분 : 2008-09-17 12 : 56 : 00.000
  • 두 번째 : 2008-09-17 12 : 56 : 53.000

핵심은 적절한 SQL 시간 범위 열거와 함께 DATEADDDATEDIFF 를 사용하는 것입니다.

declare @datetime datetime;
set @datetime = getdate();
select @datetime;
select dateadd(year,datediff(year,0,@datetime),0);
select dateadd(month,datediff(month,0,@datetime),0);
select dateadd(day,datediff(day,0,@datetime),0);
select dateadd(hour,datediff(hour,0,@datetime),0);
select dateadd(minute,datediff(minute,0,@datetime),0);
select dateadd(second,datediff(second,'2000-01-01',@datetime),'2000-01-01');
select dateadd(week,datediff(week,0,@datetime),-1); --Beginning of week is Sunday
select dateadd(week,datediff(week,0,@datetime),0); --Beginning of week is Monday

초 단위로 바닥을 칠할 때 0을 사용하면 산술 오버플로가 발생하는 경우가 많습니다. 따라서 바닥을 내려고 시도하는 날짜 시간보다 낮은 것으로 보장되는 알려진 값을 선택하십시오.


SQL Server에서이를 수행하는 약간의 트릭이 있습니다.

SELECT CAST(FLOOR(CAST(CURRENT_TIMESTAMP AS float)) AS DATETIME)

DateTime을 부동 소수점으로 캐스트하면 날짜는 정수 부분으로, 시간은 하루의 비율로 나타냅니다. 소수 부분을 잘라낸 다음 다시 DateTime으로 캐스트하면 그날의 시작에 자정이 있습니다.

이것은 아마도 모든 DATEADD 및 DATEDIFF 항목보다 더 효율적일 것입니다. 확실히 입력하기가 훨씬 쉽습니다.


Convert / Cast 솔루션을 확장하면 Microsoft SQL Server 2008에서 다음을 수행 할 수 있습니다.

cast(cast(getdate() as date) as datetime)

getdate()datetime 인 열로 바꾸십시오 .

이 변환과 관련된 문자열이 없습니다.

임시 쿼리 또는 업데이트에는 괜찮지 만 키 조인이나 많이 사용되는 처리의 경우 처리 내에서 변환을 처리하거나 적절한 키와 데이터를 갖도록 테이블을 재정의하는 것이 더 나을 수 있습니다.

2005 년에는 더 지저분한 바닥을 사용할 수 있습니다. cast(floor(cast(getdate() as float)) as datetime)

나는 그것이 문자열 변환을 사용한다고 생각하지 않지만 실제 효율성과 안락 의자 추정치를 비교하는 것은 말할 수 없습니다.


나는 바닥재 날짜를 기준으로 수년 동안 @Portman의 답변을 여러 번 사용했으며 유용하다고 생각할 수있는 기능으로 작업을 옮겼습니다.

나는 그 성능에 대해 어떠한 주장도하지 않으며 단지 사용자를위한 도구로 제공합니다.

이 답변을 찬성하기로 결정했다면 내 코드가 그의 파생물이기 때문에 @Portman의 답변 도 찬성하십시오 .

IF OBJECT_ID('fn_FloorDate') IS NOT NULL DROP FUNCTION fn_FloorDate
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[fn_FloorDate] (
  @Date DATETIME = NULL,
  @DatePart VARCHAR(6) = 'day'
)
RETURNS DATETIME
AS
BEGIN
  IF (@Date IS NULL)
    SET @Date = GETDATE();

  RETURN
  CASE
    WHEN LOWER(@DatePart) = 'year' THEN DATEADD(YEAR, DATEDIFF(YEAR, 0, @Date), 0)
    WHEN LOWER(@DatePart) = 'month' THEN DATEADD(MONTH, DATEDIFF(MONTH, 0, @Date), 0)
    WHEN LOWER(@DatePart) = 'day' THEN DATEADD(DAY, DATEDIFF(DAY, 0, @Date), 0)
    WHEN LOWER(@DatePart) = 'hour' THEN DATEADD(HOUR, DATEDIFF(HOUR, 0, @Date), 0)
    WHEN LOWER(@DatePart) = 'minute' THEN DATEADD(MINUTE, DATEDIFF(MINUTE, 0, @Date), 0)
    WHEN LOWER(@DatePart) = 'second' THEN DATEADD(SECOND, DATEDIFF(SECOND, '2000-01-01', @Date), '2000-01-01')
    ELSE DATEADD(DAY, DATEDIFF(DAY, 0, @Date), 0)
  END;
END

용법:

DECLARE @date DATETIME;
SET @date = '2008-09-17 12:56:53.430';

SELECT
  @date AS [Now],--2008-09-17 12:56:53.430
  dbo.fn_FloorDate(@date, 'year') AS [Year],--2008-01-01 00:00:00.000
  dbo.fn_FloorDate(default, default) AS [NoParams],--2013-11-05 00:00:00.000
  dbo.fn_FloorDate(@date, default) AS [ShouldBeDay],--2008-09-17 00:00:00.000
  dbo.fn_FloorDate(@date, 'month') AS [Month],--2008-09-01 00:00:00.000
  dbo.fn_FloorDate(@date, 'day') AS [Day],--2008-09-17 00:00:00.000
  dbo.fn_FloorDate(@date, 'hour') AS [Hour],--2008-09-17 12:00:00.000
  dbo.fn_FloorDate(@date, 'minute') AS [Minute],--2008-09-17 12:56:00.000
  dbo.fn_FloorDate(@date, 'second') AS [Second];--2008-09-17 12:56:53.000

CONVERT () 함수를 사용 어떤 스타일에 따라,뿐만 아니라이 작업을 수행 할 수 있습니다.


안타깝게도 Oracle이 아니거나 trunc () 또는 to_char ()를 사용할 수 있습니다.

But I had similar issues with SQL Server and used the CONVERT() and DateDiff() methods, as referenced here


There are several ways to skin this cat =)

select convert(datetime,convert(varchar,CURRENT_TIMESTAMP,101))

DateAdd along with DateDiff can help to do many different tasks. For example, you can find last day of any month as well can find last day of previous or next month.

----Last Day of Previous Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0))
LastDay_PreviousMonth
----Last Day of Current Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))
LastDay_CurrentMonth
----Last Day of Next Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+2,0))
LastDay_NextMonth

Source


Since PostgreSQL is also a "SQL Server", I'll mention

date_trunc()

Which does exactly what you're asking gracefully.

For example:

 select date_trunc('hour',current_timestamp);
       date_trunc
------------------------
 2009-02-18 07:00:00-08
(1 row)

참고URL : https://stackoverflow.com/questions/85373/floor-a-date-in-sql-server

반응형