【问题标题】:SQL - creating a list of custom dates between two datesSQL - 创建两个日期之间的自定义日期列表
【发布时间】:2015-12-14 10:40:39
【问题描述】:

我无法编译查询,但无法执行以下操作:

  1. 我有一张表,其中包含 startDateendDate [tblPayments]
  2. 我有一个存储特定 paymentDay [tblPayments]
  3. 的列

数据

paymentID        startDate           endDate          paymentDay
    1            2016-01-01         2016-12-31            25
    2            2015-06-01         2016-06-30            16

我正在尝试生成一个 SELECT 查询,它将根据这两个日期之间的月数将此特定表拆分为单独的行,并将 paymentDay 设置为这些查询的日期

示例输出

paymentID       expectedDate
    1            2016-01-25   
    1            2016-02-25   
    1            2016-03-25   
    1            2016-04-25   
    1            2016-05-25   
    1            2016-06-25   
    1            2016-07-25   
    1            2016-08-25   
    1            2016-09-25   
    1            2016-10-25   
    1            2016-11-25   
    1            2016-12-25   
    2            2015-06-16   
    2            2015-07-16  
    2            2015-08-16  
    2            2015-09-16  
    2            2015-10-16  
    2            2015-11-16  
    2            2015-12-16  
    2            2016-01-16  
    2            2016-02-16  
    2            2016-03-16  
    2            2016-04-16  
    2            2016-05-16  

我找到了一个查询,它将选择这些日期之间的月份,但它会根据我上面的表格以及我正在努力解决的多个 startDates 和 endDates 进行调整

拆分月份

declare @start DATE = '2015-01-01'
declare @end DATE = '2015-12-31'

;with months (date)
AS
(
    SELECT @start
    UNION ALL
    SELECT DATEADD(MM,1,date)
    from months
    where DATEADD(MM,1,date)<=@end
)
select Datename(MM,date) from months

这个查询仅限于一个startDateendDate,所以我没有扩展它来改变日期的DAY

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    使用日期表和简单的内部联接

    DECLARE @tblPayments table (paymentID int identity(1,1), startDate date, endDate date, paymentDay int)
    
    INSERT @tblPayments VALUES 
      ('2016-01-01', '2016-12-31', 25), 
      ('2015-06-01', '2016-06-30', 16)
    
    
    
    ;WITH dates AS -- Build date within the range of startDate and endDate
    (
        SELECT MIN(startDate) AS Value, MAX(endDate) AS MaxDate FROM @tblPayments
        UNION ALL 
        SELECT DATEADD(DAY, 1, Value), MaxDate 
        FROM dates WHERE DATEADD(DAY, 1, Value) <= MaxDate
    )
    SELECT pay.paymentID, dates.Value AS expectedDate 
    FROM 
        @tblPayments pay 
        INNER JOIN dates ON 
            dates.Value BETWEEN pay.startDate AND pay.endDate 
            AND DAY(dates.Value) = paymentDay
    OPTION (maxrecursion 0)
    

    【讨论】:

    • 谢谢,这也有效,我所做的只是用 select 语句交换 INSERT 代码,这会获取整个表的值
    【解决方案2】:

    我会在内存中创建一个日历表,然后通过加入它来执行一个简单的查询:

    -- Create a table with all the dates between the min and max dates in the 
    -- data table
    DECLARE @Calendar TABLE
    (
        [CalendarDate] DATETIME
    )
    
    DECLARE @StartDate DATETIME
    DECLARE @EndDate DATETIME
    SELECT @StartDate = MIN(startdate), @EndDate = MAX(enddate) FROM YourDataTable
    
    WHILE @StartDate <= @EndDate
    BEGIN
        INSERT INTO @Calendar (CalendarDate)
        SELECT @StartDate
        SET @StartDate = DATEADD(dd, 1, @StartDate)
    END
    
    -- Join to return only dates between the start and end date that match the Payment Day
    SELECT D.PaymentId, C.CalendarDate FROM YourDataTable D
    INNER JOIN @Calendar C ON C.CalendarDate BETWEEN D.StartDate AND D.EndDate
    AND DATEPART(day, C.CalendarDate) = D.PaymentDay
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多