복붙노트

[SQL] SQL에서 두 날짜 사이의 전체 개월 수를 계산

SQL

SQL에서 두 날짜 사이의 전체 개월 수를 계산

나는 SQL, 즉 전체 달의 수를 계산해야

나는 DATEDIFF, 즉를 사용하려고

SELECT DATEDIFF(MONTH, '2009-04-16', '2009-05-15')

대신 두 날짜 사이에 나에게 전체 개월을주는, 그것은 나에게 월 부분, 즉의 차이를 제공합니다

1

사람이 SQL Server의 전체 개월의 수를 계산하는 방법을 알아?

해결법

  1. ==============================

    1.원래 포스트는 ... 몇 가지 버그가 있었다 나는 그래서 다시 작성하고 UDF로 포장.

    원래 포스트는 ... 몇 가지 버그가 있었다 나는 그래서 다시 작성하고 UDF로 포장.

    CREATE FUNCTION FullMonthsSeparation 
    (
        @DateA DATETIME,
        @DateB DATETIME
    )
    RETURNS INT
    AS
    BEGIN
        DECLARE @Result INT
    
        DECLARE @DateX DATETIME
        DECLARE @DateY DATETIME
    
        IF(@DateA < @DateB)
        BEGIN
            SET @DateX = @DateA
            SET @DateY = @DateB
        END
        ELSE
        BEGIN
            SET @DateX = @DateB
            SET @DateY = @DateA
        END
    
        SET @Result = (
                        SELECT 
                        CASE 
                            WHEN DATEPART(DAY, @DateX) > DATEPART(DAY, @DateY)
                            THEN DATEDIFF(MONTH, @DateX, @DateY) - 1
                            ELSE DATEDIFF(MONTH, @DateX, @DateY)
                        END
                        )
    
        RETURN @Result
    END
    GO
    
    SELECT dbo.FullMonthsSeparation('2009-04-16', '2009-05-15') as MonthSep -- =0
    SELECT dbo.FullMonthsSeparation('2009-04-16', '2009-05-16') as MonthSep -- =1
    SELECT dbo.FullMonthsSeparation('2009-04-16', '2009-06-16') as MonthSep -- =2
    
  2. ==============================

    2.

    select case when DATEPART(D,End_dATE) >=DATEPART(D,sTAR_dATE) 
    THEN ( case when DATEPART(M,End_dATE) = DATEPART(M,sTAR_dATE) AND DATEPART(YYYY,End_dATE) = DATEPART(YYYY,sTAR_dATE) 
            THEN 0 ELSE DATEDIFF(M,sTAR_dATE,End_dATE)END )
    ELSE DATEDIFF(M,sTAR_dATE,End_dATE)-1 END
    
  3. ==============================

    3.DATEADD 함수는 달의 시작 부분 상쇄 할 수 있습니다. endDate가 덜 startDate를보다 일 부분이있는 경우,이 전월에 밀어 얻을 것이다, 따라서 DATEDIFF 달의 정확한 수를 줄 것이다.

    DATEADD 함수는 달의 시작 부분 상쇄 할 수 있습니다. endDate가 덜 startDate를보다 일 부분이있는 경우,이 전월에 밀어 얻을 것이다, 따라서 DATEDIFF 달의 정확한 수를 줄 것이다.

    DATEDIFF(MONTH, DATEADD(DAY,-DAY(startDate)+1,startDate),DATEADD(DAY,-DAY(startDate)+1,endDate))
    
  4. ==============================

    4.달의 당신의 정의는 무엇입니까? 기술적으로 한 달은 달과 도약 년에 따라 28,29,30 또는 삼십일일 될 수 있습니다.

    달의 당신의 정의는 무엇입니까? 기술적으로 한 달은 달과 도약 년에 따라 28,29,30 또는 삼십일일 될 수 있습니다.

    왜 그냥 다음을 수행, 당신이 당신의 예를 들어 당신이 월 31 일이 것을 무시하기 때문에 한 달에 30 일로 고려하고 보인다?

    SELECT DATEDIFF(DAY, '2009-04-16', '2009-05-15')/30
        , DATEDIFF(DAY, '2009-04-16', '2009-05-16')/30
        , DATEDIFF(DAY, '2009-04-16', '2009-06-16')/30
    
  5. ==============================

    5.이것은 단지가 아닌 SQL-Server에 대한 ORACLE위한 것입니다 :

    이것은 단지가 아닌 SQL-Server에 대한 ORACLE위한 것입니다 :

    months_between(to_date ('2009/05/15', 'yyyy/mm/dd'), 
                   to_date ('2009/04/16', 'yyyy/mm/dd'))
    

    그리고 전체 월 :

    round(months_between(to_date ('2009/05/15', 'yyyy/mm/dd'), 
                         to_date ('2009/04/16', 'yyyy/mm/dd')))
    

    오라클 8i를과 이상 사용할 수 있습니다.

  6. ==============================

    6.DATEDIFF ()는 지정된 기간에 대한 두 날짜 사이에 교차 수 경계를 반환하도록 설계되었습니다. 당신이 원하는 것을 할 그것을 얻으려면, 당신은 날짜가 경계를 통과하지만 전체 범위를 완료하지 않은 경우에 대한 계정에 추가 조정을 할 필요가있다.

    DATEDIFF ()는 지정된 기간에 대한 두 날짜 사이에 교차 수 경계를 반환하도록 설계되었습니다. 당신이 원하는 것을 할 그것을 얻으려면, 당신은 날짜가 경계를 통과하지만 전체 범위를 완료하지 않은 경우에 대한 계정에 추가 조정을 할 필요가있다.

  7. ==============================

    7.

    WITH   
    -- Count how many months must be added to @StartDate to exceed @DueDate  
    MONTHS_SINCE(n, [Month_hence], [IsFull], [RemainingDays] ) AS (  
    SELECT   
        1 as n,  
        DATEADD(Day, -1, DATEADD(Month, 1, @StartDate)) AS Month_hence  
        ,CASE WHEN (DATEADD(Day, -1, DATEADD(Month, 1, @StartDate)) <= @LastDueDate)   
            THEN 1   
            ELSE 0   
        END  AS [IsFull]  
        ,DATEDIFF(day, @StartDate,  @LastDueDate) as [RemainingDays]  
    UNION ALL  
    SELECT  
        n+1,  
        --DateAdd(Month, 1, Month_hence) as Month_hence -- No, causes propagation of short month discounted days  
        DATEADD(Day, -1, DATEADD(Month, n+1, @StartDate)) as Month_hence  
        ,CASE WHEN (DATEADD(Day, -1, DATEADD(Month, n+1, @StartDate)) <= @LastDueDate)   
            THEN 1   
            ELSE 0    
        END  AS [IsFull]  
        ,DATEDIFF(day, DATEADD(Day, -1, DATEADD(Month, n, @StartDate)),  @LastDueDate)  
        FROM MONTHS_SINCE   
        WHERE Month_hence<( @LastDueDate --WHERE Period= 1  
        )  
    ), --SELECT * FROM MONTHS_SINCE  
    MONTH_TALLY (full_months_over_all_terms, months_over_all_terms, days_in_incomplete_month ) AS (  
    SELECT  
        COALESCE((SELECT MAX(n) FROM MONTHS_SINCE WHERE isFull = 1),1) as full_months_over_all_terms,  
        (SELECT MAX(n) FROM MONTHS_SINCE ) as months_over_all_terms,  
        COALESCE((SELECT [RemainingDays] FROM MONTHS_SINCE WHERE isFull = 0),0) as days_in_incomplete_month  
    ) SELECT * FROM MONTH_TALLY;   
    
  8. ==============================

    8.단지 @result 일부 기능을 만들 필요가 없습니다. 예를 들면 :

    단지 @result 일부 기능을 만들 필요가 없습니다. 예를 들면 :

    Select Name,
    (SELECT CASE WHEN 
    DATEPART(DAY, '2016-08-28') > DATEPART(DAY, '2016-09-29')   
    THEN DATEDIFF(MONTH, '2016-08-28',  '2016-09-29') - 1
    ELSE DATEDIFF(MONTH, '2016-08-28',  '2016-09-29') END) as NumberOfMonths
    
    FROM 
    tableExample;
    
  9. ==============================

    9.이 대답은 T-SQL 형식을 따른다. 나는, 날짜 형식이 날짜의 사이에 선형 시간 거리의 하나로서이 문제를 개념화 시간 1 및 타임 2 그들에게 전화; 시간 1 당신이 (출생 날짜 나 위젯 작성 날짜 또는 여행 시작 날짜를 말한다) 및 타임 2는 '새로운 시간'값으로 정렬되어야합니다 다루고있는 '오래된 시간'값으로 정렬되어야합니다 (스냅 샷의 날짜를 말한다 위젯 완료 날짜 또는 여행 체크 포인트-에 도달 날짜) 나.

    이 대답은 T-SQL 형식을 따른다. 나는, 날짜 형식이 날짜의 사이에 선형 시간 거리의 하나로서이 문제를 개념화 시간 1 및 타임 2 그들에게 전화; 시간 1 당신이 (출생 날짜 나 위젯 작성 날짜 또는 여행 시작 날짜를 말한다) 및 타임 2는 '새로운 시간'값으로 정렬되어야합니다 다루고있는 '오래된 시간'값으로 정렬되어야합니다 (스냅 샷의 날짜를 말한다 위젯 완료 날짜 또는 여행 체크 포인트-에 도달 날짜) 나.

    DECLARE @Time1 DATETIME
    SET @Time1 = '12/14/2015'
    
    DECLARE @Time2 DATETIME
    SET @Time2 = '12/15/2016'
    

    상기 용액은 단순 측정, 변환 및 상이한 길이의 다중 사이클의 일련의 교차점 계산을 활용; 여기 : 세기 십 년간, 년, 월, 일 (개념에 대한 감사 마야 달력!). 감사의 빠른 참고 : 내가 함께 바느질 한 것으로이 과정에서 나에게 구성 요소의 일부 기능을 보여주는 스택 오버플로 다른 참여자 감사합니다. 나는 긍정적으로이 포럼에 내 시간에 이러한 평가했습니다.

    첫째, 세기 월별, 십 년간, 년, 월주기, 증분의 교차점의 선형 집합 인 지평선을 구성. 십자가는이에 대해 직교 기능을 결합합니다. (우리가 거리 측정하기 위해 두 개의 'YYYY-MM'점 사이의 길이를 잘라 버릴 꺼야있는 옷감을 만들기로 생각하십시오) :

    SELECT 
    Linear_YearMonths = (centuries.century + decades.decade + years.[year] + months.[Month]),
    1 AS value
    INTO #linear_months
    FROM
    (SELECT '18' [century] UNION ALL
    SELECT '19' UNION ALL
    SELECT '20') centuries 
    CROSS JOIN 
    (SELECT '0' [decade] UNION ALL
    SELECT '1' UNION ALL
    SELECT '2' UNION ALL
    SELECT '3' UNION ALL
    SELECT '4' UNION ALL
    SELECT '5' UNION ALL
    SELECT '6' UNION ALL
    SELECT '7' UNION ALL
    SELECT '8' UNION ALL
    SELECT '9') decades 
    CROSS JOIN 
    (SELECT '1' [year] UNION ALL
    SELECT '2' UNION ALL
    SELECT '3' UNION ALL
    SELECT '4' UNION ALL
    SELECT '5' UNION ALL
    SELECT '6' UNION ALL
    SELECT '7' UNION ALL
    SELECT '8' UNION ALL
    SELECT '9' UNION ALL
    SELECT '0') years 
    CROSS JOIN  
    (SELECT '-01' [month] UNION ALL
    SELECT '-02' UNION ALL
    SELECT '-03' UNION ALL
    SELECT '-04' UNION ALL
    SELECT '-05' UNION ALL
    SELECT '-06' UNION ALL
    SELECT '-07' UNION ALL
    SELECT '-08' UNION ALL
    SELECT '-09' UNION ALL
    SELECT '-10' UNION ALL
    SELECT '-11' UNION ALL
    SELECT '-12') [months]
    ORDER BY 1
    

    그런 다음, 'YYYY-MM'형식으로 시간 1 및 타임 2 날짜 포인트를 변환 (전체 천의 좌표 컷 지점으로 이러한 생각). 뿐만 아니라 지점의 원래 날짜 버전을 유지 :

    SELECT
    Time1 = @Time1,
    [YYYY-MM of Time1] = CASE
    WHEN LEFT(MONTH(@Time1),1) <> '1' OR MONTH(@Time1) = '1'
        THEN (CAST(YEAR(@Time1) AS VARCHAR) + '-' + '0' + CAST(MONTH(@Time1) AS VARCHAR))
        ELSE (CAST(YEAR(@Time1) AS VARCHAR) + '-' + CAST(MONTH(@Time1) AS VARCHAR))
        END,
    Time2 = @Time2,
    [YYYY-MM of Time2] = CASE
    WHEN LEFT(MONTH(@Time2),1) <> '1' OR MONTH(@Time2) = '1'
        THEN (CAST(YEAR(@Time2) AS VARCHAR) + '-' + '0' + CAST(MONTH(@Time2) AS VARCHAR))
        ELSE (CAST(YEAR(@Time2) AS VARCHAR) + '-' + CAST(MONTH(@Time2) AS VARCHAR))
        END
    INTO #datepoints
    

    그런 다음, 'YYYY-MM'단위의 서수 거리를 선택하고, 덜 하나 (즉, 식별 된 컷 지점에서 전체 천 헝겊 조각을 잘라 원시 측정을 얻을) 추기경 거리로 변환 :

    SELECT 
    d.*,
    Months_Between = (SELECT (SUM(l.value) - 1) FROM #linear_months l
                WHERE l.[Linear_YearMonths] BETWEEN d.[YYYY-MM of Time1] AND d.[YYYY-MM of Time2])
    FROM #datepoints d
    

    원시 출력 : 나는 '원시 거리'는 'YYYY-MM'추기경 거리의 월 구성 요소가 너무 많은 일을 할 수 있기 때문에이 부르는; 달 필요 내 일주기의 구성 요소는이 지난달 값을 계산해야하는지 비교한다. 특히이 예에서는, 원료 출력 거리는 '12'이다. 그러나 12/14로이 잘못 그렇게 때문에 단지 11 전체 개월이 경과 한 12/15 이전 인 - 그 한 날이 12 월을 통해 빠져들지의 주저. 따라서 우리는 최종 답을 얻기 위해 내 월 일주기에 가지고해야합니다. 명목상 여부를 최근 날짜 포인트 개월 카운트를 결정하기 위해 사이에 '월, 일의 입장 비교를 삽입합니다 :

    SELECT 
    d.*,
    Months_Between = (SELECT (SUM(l.value) - 1) FROM AZ_VBP.[MY].[edg_Linear_YearMonths] l
                WHERE l.[Linear_YearMonths] BETWEEN d.[YYYY-MM of Time1] AND d.[YYYY-MM of Time2])
            + (CASE WHEN DAY(Time1) < DAY(Time2)
                    THEN -1
                    ELSE 0
                    END)
    FROM #datepoints d
    

    최종 출력 : '11'의 정답은 지금 우리의 출력됩니다. 그래서, 난이 도움이되기를 바랍니다. 감사!

  10. ==============================

    10.

    select CAST(DATEDIFF(MONTH, StartDate, EndDate) AS float) -
      (DATEPART(dd,StartDate) - 1.0) / DATEDIFF(DAY, StartDate, DATEADD(MONTH, 1, StartDate)) +
      (DATEPART(dd,EndDate)*1.0 ) / DATEDIFF(DAY, EndDate, DATEADD(MONTH, 1, EndDate))
    
  11. ==============================

    11.나는 이것이 이전 게시물입니다 알지만 내가 CASE 문을 사용하여 쉽게 구현할 수있다 생각이 흥미로운 솔루션을 만들었습니다.

    나는 이것이 이전 게시물입니다 알지만 내가 CASE 문을 사용하여 쉽게 구현할 수있다 생각이 흥미로운 솔루션을 만들었습니다.

    DATEDIFF를 사용하여 차이를 추정하고, 그 전에 최고의 날짜를 찾을 DATEADD 사용 후 몇 달을 테스트합니다. (이 때문에)이 2 월 28 년 1 월 (31) 가정를 1 달.

    DECLARE @First date = '2015-08-31'
    DECLARE @Last date = '2016-02-28'
    
    SELECT
        @First as [First],
        @Last as [Last],
        DateDiff(Month, @First, @Last) as [DateDiff Thinks],
        CASE
            WHEN DATEADD(Month, DATEDIFF(Month, @First, @Last) +1, @First) <= @Last Then DATEDIFF(Month, @First, @Last) +1
            WHEN DATEADD(Month, DATEDIFF(Month, @First, @Last) , @First) <= @Last Then DATEDIFF(Month, @First, @Last) 
            WHEN DATEADD(Month, DATEDIFF(Month, @First, @Last) -1, @First) <= @Last Then DATEDIFF(Month, @First, @Last) -1
        END as [Actual Months Apart]
    
  12. ==============================

    12.간단하고 쉬운 방법, 그냥 복사하여 MS SQL이 FULL 코드를 붙여 및 실행 :

    간단하고 쉬운 방법, 그냥 복사하여 MS SQL이 FULL 코드를 붙여 및 실행 :

    declare @StartDate date='2019-01-31'
    declare @EndDate date='2019-02-28'
    
    
    SELECT
    
    DATEDIFF(MONTH, @StartDate, @EndDate)+
    
    (
    
    case 
    
    when format(@StartDate,'yyyy-MM') != format(@EndDate,'yyyy-MM') AND DATEPART(DAY,@StartDate) > DATEPART(DAY,@EndDate) AND DATEPART(DAY,@EndDate) = DATEPART(DAY,EOMONTH(@EndDate)) then 0
    
    when format(@StartDate,'yyyy-MM') != format(@EndDate,'yyyy-MM') AND DATEPART(DAY,@StartDate) > DATEPART(DAY,@EndDate)  then -1 
    
    else 0 
    
    end
    
    ) 
    
    as NumberOfMonths
    
  13. ==============================

    13.당신이해야 할 모든 종료 날짜가 아직 시작 날짜에 그 달의 날짜를 통과하지 않은 경우 추가로 달 공제입니다.

    당신이해야 할 모든 종료 날짜가 아직 시작 날짜에 그 달의 날짜를 통과하지 않은 경우 추가로 달 공제입니다.

    DECLARE @StartDate AS DATE = '2019-07-17'
    DECLARE @EndDate AS DATE = '2019-09-15'
    
    
    DECLARE @MonthDiff AS INT = DATEDIFF(MONTH,@StartDate,@EndDate)
    
    SELECT @MonthDiff - 
            CASE 
                WHEN FORMAT(@StartDate,'dd') > FORMAT(@EndDate,'dd') THEN 1
                ELSE 0
            END
    
  14. ==============================

    14.

    SELECT 12 * (YEAR(end_date) - YEAR(start_date)) +
        ((MONTH(end_date) - MONTH(start_date))) +
        SIGN(DAY(end_date) / DAY(start_date));
    

    이는 SQL 서버 2000에 나를 위해 잘 작동합니다.

  15. ==============================

    15.시험:

    시험:

    trunc(Months_Between(date2, date1))
    
  16. ==============================

    16.나는 인터넷을 통해 봤. 그리고 제안 I의 발견되었습니다 끝에 1을 추가하는 것입니다.

    나는 인터넷을 통해 봤. 그리고 제안 I의 발견되었습니다 끝에 1을 추가하는 것입니다.

    이런 식으로 작업을 수행하십시오 :

    Declare @Start DateTime
    Declare @End DateTime
    
    Set @Start = '11/1/07'
    Set @End = '2/29/08'
    
    Select DateDiff(Month, @Start, @End + 1)
    
  17. from https://stackoverflow.com/questions/1106945/calculating-number-of-full-months-between-two-dates-in-sql by cc-by-sa and MIT license