복붙노트

[SQL] SQL Server의 두 날짜 사이의 모든 날짜를 가져옵니다

SQL

SQL Server의 두 날짜 사이의 모든 날짜를 가져옵니다

어떻게 두 날짜 사이의 날짜를 얻으려면?

I 테이블로부터 최대 날짜를 기억하는 변수 @MAXDATE있다. 지금은 @Maxdate과 GETDATE (사이의 모든 날짜를 얻을)와 커서의이 날짜를 저장할 싶습니다.

다음과 같이 지금까지 내가했던 :

;with GetDates As  
(  
select DATEADD(day,1,@maxDate) as TheDate
UNION ALL  
select DATEADD(day,1, TheDate) from GetDates  
where TheDate < GETDATE()  
)  

이 완벽하게 작동하지만 난 커서에서이 값을 저장하려고 할 때

SET @DateCurSor=CURSOR FOR
                SELECT TheDate
                FROM GetDates

컴파일 오류

이 문제를 해결하는 방법.

미리 감사드립니다

해결법

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

    1.계정이없는 경우 내 첫 제안은 다음을 작성, 캘린더 테이블을 사용하는 것입니다. 그들은 매우 유용합니다. 귀하의 질문은 간단하게 다음입니다 :

    계정이없는 경우 내 첫 제안은 다음을 작성, 캘린더 테이블을 사용하는 것입니다. 그들은 매우 유용합니다. 귀하의 질문은 간단하게 다음입니다 :

    DECLARE @MinDate DATE = '20140101',
            @MaxDate DATE = '20140106';
    
    SELECT  Date
    FROM    dbo.Calendar
    WHERE   Date >= @MinDate
    AND     Date < @MaxDate;
    

    당신은하고 싶지 않아, 또는 당신은 여전히 ​​재귀 CTE없이 즉석에서이 작업을 수행 할 수있는 달력 테이블을 만들 수없는 경우 :

    DECLARE @MinDate DATE = '20140101',
            @MaxDate DATE = '20140106';
    
    SELECT  TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1)
            Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @MinDate)
    FROM    sys.all_objects a
            CROSS JOIN sys.all_objects b;
    

    이 페이지의 더 읽기 :

    다음 커서의 날짜의 시퀀스를 사용에 관해서는, 정말 다른 방법을 찾아 추천 할 것입니다. 더 나은 수행합니다 세트를 기반으로 대안은 일반적으로있다.

    당신의 데이터 그래서 :

      date   | it_cd | qty 
    24-04-14 |  i-1  | 10 
    26-04-14 |  i-1  | 20
    

    (나는 당신의 필요 조건이 수집) 28-04-2014에 양을 얻으려면, 당신은 실제로 위의 필요하지 않습니다, 당신은 단순히 사용할 수 있습니다 :

    SELECT  TOP 1 date, it_cd, qty 
    FROM    T
    WHERE   it_cd = 'i-1'
    AND     Date <= '20140428'
    ORDER BY Date DESC;
    

    당신은 특정 항목에 대한 그것을 원하지 않는 경우 :

    SELECT  date, it_cd, qty 
    FROM    (   SELECT  date, 
                        it_cd, 
                        qty, 
                        RowNumber = ROW_NUMBER() OVER(PARTITION BY ic_id 
                                                        ORDER BY date DESC)
                FROM    T
                WHERE   Date  <= '20140428'
            ) T
    WHERE   RowNumber = 1;
    
  2. ==============================

    2.두 날짜 사이의 날짜를 찾기 위해이 스크립트를 사용할 수 있습니다. 이 조에서 가져온 참조 :

    두 날짜 사이의 날짜를 찾기 위해이 스크립트를 사용할 수 있습니다. 이 조에서 가져온 참조 :

    DECLARE @StartDateTime DATETIME
    DECLARE @EndDateTime DATETIME
    
    SET @StartDateTime = '2015-01-01'
    SET @EndDateTime = '2015-01-12';
    
    WITH DateRange(DateData) AS 
    (
        SELECT @StartDateTime as Date
        UNION ALL
        SELECT DATEADD(d,1,DateData)
        FROM DateRange 
        WHERE DateData < @EndDateTime
    )
    SELECT DateData
    FROM DateRange
    OPTION (MAXRECURSION 0)
    GO
    
  3. ==============================

    3.쉽게 모든 날짜와 테이블을 반환하는 테이블 값 함수를 만듭니다. 문자열로 입력 날짜 당신은 형식으로 날짜를 사용자 정의 할 수 있습니다 문자열 형식으로 '01 / 01 / 2017 '또는 '01 -01-2017'(103,126 ...)와 같은

    쉽게 모든 날짜와 테이블을 반환하는 테이블 값 함수를 만듭니다. 문자열로 입력 날짜 당신은 형식으로 날짜를 사용자 정의 할 수 있습니다 문자열 형식으로 '01 / 01 / 2017 '또는 '01 -01-2017'(103,126 ...)와 같은

    이 시도

    CREATE FUNCTION [dbo].[DateRange_To_Table] ( @minDate_Str NVARCHAR(30), @maxDate_Str NVARCHAR(30))
    
    RETURNS  @Result TABLE(DateString NVARCHAR(30) NOT NULL, DateNameString NVARCHAR(30) NOT NULL)
    
    AS
    
    begin
    
        DECLARE @minDate DATETIME, @maxDate DATETIME
        SET @minDate = CONVERT(Datetime, @minDate_Str,103)
        SET @maxDate = CONVERT(Datetime, @maxDate_Str,103)
    
    
        INSERT INTO @Result(DateString, DateNameString )
        SELECT CONVERT(NVARCHAR(10),@minDate,103), CONVERT(NVARCHAR(30),DATENAME(dw,@minDate))
    
    
    
        WHILE @maxDate > @minDate
        BEGIN
            SET @minDate = (SELECT DATEADD(dd,1,@minDate))
            INSERT INTO @Result(DateString, DateNameString )
            SELECT CONVERT(NVARCHAR(10),@minDate,103), CONVERT(NVARCHAR(30),DATENAME(dw,@minDate))
        END
    
    
    
    
        return
    
    end   
    

    함수가이를 실행하려면 :

    SELECT * FROM dbo.DateRange_To_Table ('01/01/2017','31/01/2017')
    

    출력 될 것입니다

    01/01/2017  Sunday
    02/01/2017  Monday
    03/01/2017  Tuesday
    04/01/2017  Wednesday
    05/01/2017  Thursday
    06/01/2017  Friday
    07/01/2017  Saturday
    08/01/2017  Sunday
    09/01/2017  Monday
    10/01/2017  Tuesday
    11/01/2017  Wednesday
    12/01/2017  Thursday
    13/01/2017  Friday
    14/01/2017  Saturday
    15/01/2017  Sunday
    16/01/2017  Monday
    17/01/2017  Tuesday
    18/01/2017  Wednesday
    19/01/2017  Thursday
    20/01/2017  Friday
    21/01/2017  Saturday
    22/01/2017  Sunday
    23/01/2017  Monday
    24/01/2017  Tuesday
    25/01/2017  Wednesday
    26/01/2017  Thursday
    27/01/2017  Friday
    28/01/2017  Saturday
    29/01/2017  Sunday
    30/01/2017  Monday
    31/01/2017  Tuesday
    
  4. ==============================

    4.그냥 여기에 좀 더 간단한 방법은 ... 말 :

    그냥 여기에 좀 더 간단한 방법은 ... 말 :

    declare @sdate date = '2017-06-25'
        , @edate date = '2017-07-24'
    
    ; with dates_CTE (date) as (
            select @sdate 
        Union ALL
            select DATEADD(day, 1, date)
            from dates_CTE
            where date < @edate
    ) select 
        *
    from dates_CTE 
    
  5. ==============================

    5., 나는 CTE 테이블을 사용할 수 없습니다 내 상황과 같이이 작업은 그래서 "sys.all_objects"다음 생성 된 행 번호와 참여를 결정하고 종료 날짜를 도달 할 때까지 일을 시작하는 것을 추가, 조금 까다로운 방법으로 고려 될 수있다.

    , 나는 CTE 테이블을 사용할 수 없습니다 내 상황과 같이이 작업은 그래서 "sys.all_objects"다음 생성 된 행 번호와 참여를 결정하고 종료 날짜를 도달 할 때까지 일을 시작하는 것을 추가, 조금 까다로운 방법으로 고려 될 수있다.

    나는 7 월 2018의 모든 날짜 (2016 SQL 서버에서 테스트) 자신의 변수를 하드 코딩 날짜를 교체 생성 된 경우 아래의 코드를 참조하십시오 :

    select top (datediff(dd, '2018-06-30', '2018-07-31')) ROW_NUMBER() 
    over(order by a.name) as SiNo, 
    Dateadd(dd, ROW_NUMBER() over(order by a.name) , '2018-06-30') as Dt from sys.all_objects a
    
  6. ==============================

    6.이 시도 할 수 있습니다 :

    이 시도 할 수 있습니다 :

        SET LANGUAGE SPANISH
    
    DECLARE @startDate DATE = GETDATE() -- Your start date
    DECLARE @endDate DATE = DATEADD(MONTH, 16, GETDATE()) -- Your end date
    DECLARE @years INT = YEAR(@endDate) - YEAR(@startDate)
    
    CREATE TABLE #TMP_YEARS (
        [year] INT
    )
    
    -- Get all posible years between the start and end date
    WHILE @years >= 0
    BEGIN
        INSERT INTO #TMP_YEARS
        ([year])
        SELECT YEAR(@startDate) + @years
    
        SET @years = @years - 1
    END
    
    ;WITH [days]([day]) AS -- Posible days at a month
    (
        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 UNION ALL -- days lower than 10
        SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15 UNION ALL SELECT 16 UNION ALL SELECT 17 UNION ALL SELECT 18 UNION ALL SELECT 19 UNION ALL -- days lower than 20
        SELECT 20 UNION ALL SELECT 21 UNION ALL SELECT 22 UNION ALL SELECT 23 UNION ALL SELECT 24 UNION ALL SELECT 25 UNION ALL SELECT 26 UNION ALL SELECT 27 UNION ALL SELECT 28 UNION ALL SELECT 29 UNION ALL -- days lower than 30
        SELECT 30 UNION ALL SELECT 31 -- days higher 30
    ),
    [months]([month]) AS -- All months at a year
    (
        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 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12
    )
    SELECT CONVERT(VARCHAR, a.[year]) + '-' + REPLICATE('0', 2 - LEN(CONVERT(VARCHAR, n.[month]))) + CONVERT(VARCHAR, n.[month]) + '-' + REPLICATE('0', 2 - LEN(CONVERT(VARCHAR, d.[day]))) + CONVERT(VARCHAR, d.[day]) as [date]
      FROM #TMP_YEARS a
     CROSS JOIN [months] n -- Join all years with all months
     INNER JOIN [days] d on DAY(EOMONTH(CONVERT(VARCHAR, a.[year]) + '-' + REPLICATE('0', 2 - LEN(CONVERT(VARCHAR, n.[month]))) + CONVERT(VARCHAR, n.[month]) + '-' + CONVERT(VARCHAR, DAY(EOMONTH(CAST(CONVERT(VARCHAR, a.[year]) + '-' + CONVERT(varchar, n.[month]) + '-15' AS DATE)))))) >= d.[day] AND -- The number of the day can't be higher than the last day of the current month and the current year
                          CONVERT(VARCHAR, a.[year]) + '-' + REPLICATE('0', 2 - LEN(CONVERT(VARCHAR, n.[month]))) + CONVERT(VARCHAR, n.[month]) + '-' + REPLICATE('0', 2 - LEN(CONVERT(VARCHAR, d.[day]))) + CONVERT(VARCHAR, d.[day]) <= ISNULL(@endDate, GETDATE()) AND -- The current date can't be higher than the end date
                          CONVERT(VARCHAR, a.[year]) + '-' + REPLICATE('0', 2 - LEN(CONVERT(VARCHAR, n.[month]))) + CONVERT(VARCHAR, n.[month]) + '-' + REPLICATE('0', 2 - LEN(CONVERT(VARCHAR, d.[day]))) + CONVERT(VARCHAR, d.[day]) >= ISNULL(@startDate, GETDATE()) -- The current date should be higher than the start date
     ORDER BY a.[year] ASC, n.[month] ASC, d.[day] ASC
    

    출력은 당신이 마음으로 날짜를 포맷 할 수 있습니다,이 같은 것입니다 :

    2019-01-24
    2019-01-25
    2019-01-26
    2019-01-27
    2019-01-28
    2019-01-29
    2019-01-30
    2019-01-31
    2019-02-01
    2019-02-02
    2019-02-03
    2019-02-04
    2019-02-05
    2019-02-06
    2019-02-07
    2019-02-08
    2019-02-09
    ...
    
  7. ==============================

    7.

    create procedure [dbo].[p_display_dates](@startdate datetime,@enddate datetime)
    as
    begin
        declare @mxdate datetime
        declare @indate datetime
        create table #daterange (dater datetime)
        insert into #daterange values (@startdate)
        set @mxdate = (select MAX(dater) from #daterange)
        while @mxdate < @enddate
            begin
                set @indate = dateadd(day,1,@mxdate)
                insert into #daterange values (@indate)
                set @mxdate = (select MAX(dater) from #daterange)
            end
        select * from #daterange
    end
    
  8. ==============================

    8.나중에 2 주 일자를 나열. 당신은 변수 @period 또는 기능 DATEDIFF를 사용할 수 있습니다 (일, @date_start, @date_end)

    나중에 2 주 일자를 나열. 당신은 변수 @period 또는 기능 DATEDIFF를 사용할 수 있습니다 (일, @date_start, @date_end)

    declare @period INT, @date_start datetime, @date_end datetime, @i int;
    
    set @period = 14
    set @date_start = convert(date,DATEADD(D, -@period, curent_timestamp))
    set @date_end = convert(date,current_timestamp)
    set @i = 1
    
    create table #datesList(dts datetime)
    insert into #datesList values (@date_start)
    while @i <= @period
        Begin
            insert into #datesList values (dateadd(d,@i,@date_start))
            set @i = @i + 1
        end
    select cast(dts as DATE) from #datesList
    Drop Table #datesList
    
  9. ==============================

    9.이것은 내가 사용하는 것이 방법입니다.

    이것은 내가 사용하는 것이 방법입니다.

    DECLARE 
        @DateFrom DATETIME = GETDATE(),
        @DateTo DATETIME = DATEADD(HOUR, -1, GETDATE() + 2); -- Add 2 days and minus one hour
    
    
    -- Dates spaced a day apart 
    
    WITH MyDates (MyDate)
    AS (
        SELECT @DateFrom
        UNION ALL
        SELECT DATEADD(DAY, 1, MyDate)
        FROM MyDates
        WHERE MyDate < @DateTo
       )
    
    SELECT 
        MyDates.MyDate
        , CONVERT(DATE, MyDates.MyDate) AS [MyDate in DATE format]
    FROM 
        MyDates;
    

    여기에 유사한 예는, 이번에 날짜는 쿼리의 작동 방식을 더 원조 이해 1 시간 간격을두고 있습니다 :

    -- Alternative example with dates spaced an hour apart
    
    WITH MyDates (MyDate)
    AS (SELECT @DateFrom
        UNION ALL
        SELECT DATEADD(HOUR, 1, MyDate)
        FROM MyDates
        WHERE MyDate < @DateTo
       )
    
    SELECT 
        MyDates.MyDate
    FROM 
        MyDates;
    

    당신이 볼 수 있듯이, 쿼리는 빠르고 정확하고 다양한입니다.

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

    10.

    DECLARE @FirstDate DATE = '2018-01-01'
    DECLARE @LastDate Date = '2018-12-31'
    DECLARE @tbl TABLE(ID INT IDENTITY(1,1) PRIMARY KEY,CurrDate date)
    INSERT @tbl VALUES( @FirstDate)
    WHILE @FirstDate < @LastDate
    BEGIN
    SET @FirstDate = DATEADD( day,1, @FirstDate)
    INSERT @tbl VALUES( @FirstDate)
    END
    INSERT @tbl VALUES( @LastDate) 
    
    SELECT * FROM @tbl
    
  11. from https://stackoverflow.com/questions/23290454/get-all-dates-between-two-dates-in-sql-server by cc-by-sa and MIT license