在SQL Server中创建日期

时间:2017-01-04 21:12:13

标签: sql-server

我有以下内容:

select distinct
    loannumber, activedt, inactivedt
from 
    smd..TABLE_NAME
where 
    loannumber = '12345678'

我希望能够创建一个列,其中包含activedtinactivedt之间每个月/日期的值。我已经看到了将日期设置为变量的想法,但在这种情况下,日期来自每个记录的表。请帮忙。感谢。

3 个答案:

答案 0 :(得分:1)

这将为您提供MONTH增量。但是,如果您想要DAY,只需在CROSS APPLY

中将MM更改为DD

我们正在创建一个带有master..spt_values的临时计数表,但是任何适当大小的表都可以

Declare @YourTable table (loannumber varchar(25),activedt date,inactivedt date)
Insert Into @YourTable values
('12345678','2016-01-01','2017-12-31')

Select A.LoanNumber
      ,B.Date
 From  @YourTable A
 Cross Apply (
       Select Top (DateDiff(MM,A.activedt,A.inactivedt)+1) Date=DateAdd(MM,Row_Number() Over (Order By (Select null))-1,A.activedt) 
         From master..spt_values 
       ) B

返回

LoanNumber  Date
12345678    2016-01-01
12345678    2016-02-01
12345678    2016-03-01
12345678    2016-04-01
12345678    2016-05-01
12345678    2016-06-01
12345678    2016-07-01
12345678    2016-08-01
12345678    2016-09-01
12345678    2016-10-01
12345678    2016-11-01
12345678    2016-12-01
12345678    2017-01-01
12345678    2017-02-01
12345678    2017-03-01
12345678    2017-04-01
12345678    2017-05-01
12345678    2017-06-01
12345678    2017-07-01
12345678    2017-08-01
12345678    2017-09-01
12345678    2017-10-01
12345678    2017-11-01
12345678    2017-12-01

答案 1 :(得分:0)

我建议使用Date Tables,在本文中,有一个广泛的解释,这个想法是你可以用于这种场景。

https://www.mssqltips.com/sqlservertip/4054/creating-a-date-dimension-or-calendar-table-in-sql-server/

使用此表,您可以在表之间进行连接并使用日期列。

答案 2 :(得分:0)

您无法击败物理日期表的性能,但如果您在非活动日期和活动日期之间的时间少于约2000天,并且只需要针对它进行临时基本查询,那么请考虑{{1对spt_values表。

由于我不确定活动和非活动日期是否总是在之前或之前(某些情况下有效>非活动状态,而其他情况有非活动< =有效),这适用于任何一种情况:

CROSS APPLY

这产生了以下结果,单个记录贷款数量从1/3到1/5:

select distinct
    loannumber, activedt, inactivedt, dtvalue
from 
    smd..TABLE_NAME
    CROSS APPLY (
        SELECT DATEADD(DD, N.number, activedt) FROM spt_values N
            WHERE N.number BETWEEN 0 AND DATEDIFF(DD, activedt, inactivedt) AND activedt <= inactivedt
        UNION ALL SELECT DATEADD(DD, N.number, inactivedt) FROM spt_values N
            WHERE N.number BETWEEN 0 AND DATEDIFF(DD, inactivedt, activedt) AND activedt > inactivedt
    ) N (dtvalue)
where 
    loannumber = '12345678'

如果你需要超越2000,那么loannumber activedt inactivedt dtvalue ---------- ---------- ---------- ---------- 12345678 2017-01-03 2017-01-05 2017-01-03 12345678 2017-01-03 2017-01-05 2017-01-04 12345678 2017-01-03 2017-01-05 2017-01-05 还有其他技术可以快速生成适当的行数。