[sql] T-SQL을 사용하여 일 월과 연도의 날짜를 만듭니다.

2007 년 12 월 1 일과 같은 개별 부분이있는 날짜를 SQL Server 2005의 날짜 / 시간으로 변환하려고합니다. 다음을 시도했습니다.

CAST(DATEPART(year, DATE)+'-'+ DATEPART(month, DATE) +'-'+ DATEPART(day, DATE) AS DATETIME)

그러나 이것은 잘못된 날짜를 초래합니다. 세 날짜 값을 올바른 날짜 시간 형식으로 바꾸는 올바른 방법은 무엇입니까?



답변

y, m, d모든 가정 은 int어떻습니까?

CAST(CAST(y AS varchar) + '-' + CAST(m AS varchar) + '-' + CAST(d AS varchar) AS DATETIME)

SQL Server 2012 이상에 대한 다른 답변 을 참조하십시오


답변

이 시도:

Declare @DayOfMonth TinyInt Set @DayOfMonth = 13
Declare @Month TinyInt Set @Month = 6
Declare @Year Integer Set @Year = 2006
-- ------------------------------------
Select DateAdd(day, @DayOfMonth - 1, 
          DateAdd(month, @Month - 1, 
              DateAdd(Year, @Year-1900, 0)))

잘 작동하고 문자열 변환을 수행하지 않는 이점이 추가되었으므로 순수한 산술 처리 (매우 빠름)이며 날짜 형식에 의존하지 않습니다. 이는 날짜 및 작은 날짜 시간 값에 대한 SQL Server의 내부 표현이 2라는 사실을 활용합니다. 부분 값 첫 번째 부분은 1900 년 1 월 1 일 이후의 일 수를 나타내는 정수이고, 두 번째 부분은 하루의 소수 부분을 나타내는 소수 부분입니다 (시간) — 따라서 정수 값 0 (영 )는 항상 1900 년 1 월 1 일 자정 아침으로 직접 변환됩니다.

또는 @brinary의 제안 덕분에

Select DateAdd(yy, @Year-1900,  
       DateAdd(m,  @Month - 1, @DayOfMonth - 1)) 

@cade Roux에서 언급 한 것처럼 SQL 2012에는 이제
DATEFROMPARTS(year, month, day)
동일한 기능을 수행하는 기본 제공 기능이 있습니다.

@brinary가 제안한 마지막 솔루션 인 2016 년 10 월 3 일에 수정되었습니다 (이 사실을 알려준 @bambams와이를 고치는 데 @brinary 감사). 년 추가를 먼저 수행하지 않으면 윤년 동안 작동하지 않는 것으로 보입니다.

select dateadd(month, @Month - 1, 
     dateadd(year, @Year-1900, @DayOfMonth - 1)); 


답변

SQL Server 2012에는 훌륭하고 오랫동안 기다려온 새로운 DATEFROMPARTS 함수가 있습니다 (날짜가 유효하지 않으면 오류가 발생합니다-이 문제에 대한 DATEADD 기반 솔루션에 대한 나의 반대 의견).

http://msdn.microsoft.com/en-us/library/hh213228.aspx

DATEFROMPARTS(ycolumn, mcolumn, dcolumn)

또는

DATEFROMPARTS(@y, @m, @d)


답변

또는 하나의 dateadd 함수 만 사용하십시오.

DECLARE @day int, @month int, @year int
SELECT @day = 4, @month = 3, @year = 2011

SELECT dateadd(mm, (@year - 1900) * 12 + @month - 1 , @day - 1)


답변

Sql Server 2012에는 부품 ( DATEFROMPARTS )을 기반으로 날짜를 만드는 기능이 있습니다 . 우리의 나머지 부분을 위해, 파트에서 날짜를 결정하는 db 함수가 있습니다 (@Charles 덕분에) …

IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[func_DateFromParts]'))
    DROP FUNCTION [dbo].[func_DateFromParts]
GO

CREATE FUNCTION [dbo].[func_DateFromParts]
(
    @Year INT,
    @Month INT,
    @DayOfMonth INT,
    @Hour INT = 0,  -- based on 24 hour clock (add 12 for PM :)
    @Min INT = 0,
    @Sec INT = 0
)
RETURNS DATETIME
AS
BEGIN

    RETURN DATEADD(second, @Sec,
            DATEADD(minute, @Min,
            DATEADD(hour, @Hour,
            DATEADD(day, @DayOfMonth - 1,
            DATEADD(month, @Month - 1,
            DATEADD(Year, @Year-1900, 0))))))

END

GO

당신은 이것을 이렇게 부를 수 있습니다 …

SELECT dbo.func_DateFromParts(2013, 10, 4, 15, 50, DEFAULT)

보고…

2013-10-04 15:50:00.000


답변

CAST 대신 CONVERT를 시도하십시오.

CONVERT는 날짜 형식을 나타내는 세 번째 매개 변수를 허용합니다.

형식 목록은 다음과 같습니다. http://msdn.microsoft.com/en-us/library/ms187928.aspx

다른 답변이 “올바른”답변으로 선택된 후 업데이트 :

이 제한을 나타내지 않고 서버의 NLS 설정에 따라 달라지는 응답이 선택된 이유를 실제로 이해하지 못합니다.


답변

당신은 또한 사용할 수 있습니다

select DATEFROMPARTS(year, month, day) as ColDate, Col2, Col3
From MyTable Where DATEFROMPARTS(year, month, day) Between @DateIni and @DateEnd

ver.2012 및 AzureSQL 이후 SQL에서 작동