【问题标题】:Split date range to multiple rows using SQL使用 SQL 将日期范围拆分为多行
【发布时间】:2016-08-15 04:22:27
【问题描述】:

我有一张桌子:

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

基本上是将行分解为年度结果的查询。我需要保留开始日期和结束日期。

【问题讨论】:

标签: sql-server datetime split rows


【解决方案1】:
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 * FROM #OutputTABLE;

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

【讨论】:

    【解决方案2】:

    查询很简单

    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 的 yearTable(又名 Tally 表)。此表中的数字不应超出此范围,否则会遇到一些令人讨厌的转换错误。

    【讨论】:

      猜你喜欢
      • 2020-02-28
      • 2013-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-03
      • 1970-01-01
      相关资源
      最近更新 更多