Sql server 使用SQL将日期范围拆分为多行
我有一张桌子:Sql server 使用SQL将日期范围拆分为多行,sql-server,datetime,split,rows,Sql Server,Datetime,Split,Rows,我有一张桌子: startdate enddate other_columns 1956-05-06 00:00:00.000 1960-04-05 00:00:00.000 myvalues 我需要一个查询,该查询将返回以下结果: startdate enddate other_columns 1956-05-06 00:00:00.000 19
startdate enddate other_columns
1956-05-06 00:00:00.000 1960-04-05 00:00:00.000 myvalues
我需要一个查询,该查询将返回以下结果:
startdate enddate other_columns
1956-05-06 00:00:00.000 1956-12-31 00:00:00.000 myvalues
1957-01-01 00:00:00.000 1957-12-31 00:00:00.000 myvalues
1958-01-01 00:00:00.000 1958-12-31 00:00:00.000 myvalues
1959-01-01 00:00:00.000 1959-12-31 00:00:00.000 myvalues
1960-01-01 00:00:00.000 1960-04-05 00:00:00.000 myvalues
基本上是一个将行分解为年度结果的查询。我需要保留开始和结束日期
CREATE TABLE #InputTABLE
(
startdate DATETIME,
enddate DATETIME,
other_columns varchar(20)
)
INSERT INTO #InputTABLE VALUES('1956-05-06','1960-04-05','myvalues');
SELECT * FROM #InputTABLE
输出:
startdate enddate other_columns
1956-05-06 00:00:00.000 1960-04-05 00:00:00.000 myvalues
查询:
CREATE TABLE #OutputTABLE
(
startdate DATETIME,
enddate DATETIME,
other_columns varchar(20)
)
DECLARE @cnt int
DECLARE @startDate datetime
DECLARE @endDate datetime
DECLARE @incr int
DECLARE @tempDate datetime
SET @startDate=(Select startdate from #InputTABLE)
SET @endDate=(Select enddate from #InputTABLE)
SET @cnt=DATEDIFF(yy,@startDate,@endDate)
SET @incr=0
SET @tempDate=DATEADD(yy,@incr,Cast(@startDate As datetime))
WHILE @cnt>=0
BEGIN
IF @cnt = 0
BEGIN
INSERT INTO #OutputTABLE VALUES(@tempDate,@endDate,'myvalues');
END
ELSE
BEGIN
insert into #OutputTABLE values(@tempDate,DATEADD(yy, DATEDIFF(yy,0,@tempDate)+1, -1),'myvalues');
END
SET @tempDate=DATEADD(yy,@incr+1,DATEADD(yy,DATEDIFF(yy,0,@startDate),0))
SET @cnt=@cnt-1
SET @incr=@incr+1
END
结果:从可输出中选择*
查询非常简单
SELECT CASE WHEN yrStart<it.startdate THEN it.startdate ELSE yrStart END AS startdate,
CASE WHEN yrEnd>it.enddate THEN it.enddate ELSE yrEnd END AS enddate,
other_columns
FROM #InputTABLE it
CROSS APPLY
(SELECT datefromparts(yr, 1, 1) yrStart, datefromparts(yr, 12, 31) yrEnd
FROM dbo.yearTable
WHERE yr >= datepart(year, it.startdate) AND yr <= datepart(year, it.enddate)
)years;
你所需要的就是一张有数字1..9999的年表,也就是理货表。此表中的数字不应超出此范围,否则会遇到一些严重的转换错误。创建一个日历表,可以是实数表,也可以是计数表,并将其与数据合并。
SELECT CASE WHEN yrStart<it.startdate THEN it.startdate ELSE yrStart END AS startdate,
CASE WHEN yrEnd>it.enddate THEN it.enddate ELSE yrEnd END AS enddate,
other_columns
FROM #InputTABLE it
CROSS APPLY
(SELECT datefromparts(yr, 1, 1) yrStart, datefromparts(yr, 12, 31) yrEnd
FROM dbo.yearTable
WHERE yr >= datepart(year, it.startdate) AND yr <= datepart(year, it.enddate)
)years;