有趣的SQL拼图

Mil*_*ric 9 sql sql-server puzzle

如果没有循环或游标,您如何获取日期间隔列表并将它们转换为1和0的字符串,以便:

  • 每个位代表从最小(所有日期)到最大(所有日期)的每一天
  • 如果该日落在任何日期间隔内,则该位为1
  • 如果那天没有落入任何间隔,则该位为0

例如,如果间隔是:

  • 2011年1月1日至2011年1月1日
  • 2011年1月4日至2011年5月5日

然后你编写的SQL应该输出11011.这是你可以使用的安装脚本:

declare @TimeSpan table
(
    start datetime
    ,finish datetime
)

-- this is a good data set, with overlapping and non-overlapping time spans
insert into @TimeSpan values ('02/02/2010', '02/02/2010')
insert into @TimeSpan values ('02/03/2010', '02/03/2010')
insert into @TimeSpan values ('02/04/2010', '02/05/2010')
insert into @TimeSpan values ('02/05/2010', '02/06/2010')
insert into @TimeSpan values ('02/07/2010', '02/09/2010')
insert into @TimeSpan values ('02/08/2010', '02/08/2010')
insert into @TimeSpan values ('02/08/2010', '02/10/2010')
insert into @TimeSpan values ('02/14/2010', '02/16/2010')

-- for this set of data, the output string would be 111111111000111
Run Code Online (Sandbox Code Playgroud)

Mar*_*ith 7

DECLARE @Result VARCHAR(MAX), @start DATETIME

SELECT @start= MIN(start) ,
       @Result =REPLICATE('0',1+DATEDIFF(DAY,MIN(start),MAX(finish)))
FROM @TimeSpan

SELECT @Result = STUFF(@Result,
                       DATEDIFF(DAY,@start,start)+1,
                       DATEDIFF(DAY,start,finish)+1,
                       REPLICATE('1',1+DATEDIFF(DAY,start,finish)))
FROM @TimeSpan 

SELECT @Result       
Run Code Online (Sandbox Code Playgroud)

  • 如果我没有充分强调它,这是一个美丽的解决方案,很棒的工作. (3认同)