Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 求解连续性的日期范围(间隙和孤岛)_Sql_Sql Server_Sql Server 2008 - Fatal编程技术网

Sql 求解连续性的日期范围(间隙和孤岛)

Sql 求解连续性的日期范围(间隙和孤岛),sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我有一个如下的表格,X列是给定起始期和结束期之间的商品价格 X START_DATE END_DATE ------------------------------ 1 01-01-2014 01-01-2016 2 01-04-2014 01-05-2014 3 01-07-2014 01-08-2014 但是,第一个分录定义的时间范围更大,只有当项目价格未定义为月度时,才应考虑该分录,类似于第二和第三个记录,或者当缺少某个范围

我有一个如下的表格,
X列
是给定起始期和结束期之间的商品价格

X    START_DATE     END_DATE
------------------------------    
1    01-01-2014     01-01-2016
2    01-04-2014     01-05-2014
3    01-07-2014     01-08-2014
但是,第一个分录定义的时间范围更大,只有当项目价格未定义为月度时,才应考虑该分录,类似于第二和第三个记录,或者当缺少某个范围时。现在理想的输出是

X    START_DATE      END_DATE
------------------------------    
1    01-01-2014     01-04-2014
2    01-04-2014     01-05-2014
1    01-05-2014     01-07-2014
3    01-07-2014     01-08-2014
1    01-08-2014     01-01-2016

我怎样才能做到这一点呢?

检查这一点,如果你高兴的话+1

-- Data Samples
declare @X table ( Price int, datefrom datetime, dateto datetime)
insert @X values ( 1, '1.1.2014','1.1.2016'),(2,'1.4.2014','1.5.2014'),(3,'1.7.2014','1.8.2014');

-- Check samples
select * from @X;

-- Query
with Dat as ( 
            select datefrom from @X
            union
            select dateto from @X 
)
, Periods as ( 
            select datefrom,dateto = LEAD(datefrom,1) over (order by datefrom) 
            from Dat
)
,val as ( select Pr.*,P.*
            from Periods P 
            cross apply ( select top 1 Price from @X
                        where P.datefrom between datefrom and dateto - 0.000001
                        order by DATEDIFF(day,datefrom,dateto)
            ) Pr

)

select * from val
输出

Price       datefrom                dateto
----------- ----------------------- -----------------------
1           2014-01-01 00:00:00.000 2016-01-01 00:00:00.000
2           2014-04-01 00:00:00.000 2014-05-01 00:00:00.000
3           2014-07-01 00:00:00.000 2014-08-01 00:00:00.000

(3 row(s) affected)

Price       datefrom                dateto
----------- ----------------------- -----------------------
1           2014-01-01 00:00:00.000 2014-04-01 00:00:00.000
2           2014-04-01 00:00:00.000 2014-05-01 00:00:00.000
1           2014-05-01 00:00:00.000 2014-07-01 00:00:00.000
3           2014-07-01 00:00:00.000 2014-08-01 00:00:00.000
1           2014-08-01 00:00:00.000 2016-01-01 00:00:00.000

(5 row(s) affected)
结果:

X           START_DATE END_DATE
----------- ---------- ----------
1           2014-01-01 2014-04-01
2           2014-04-01 2014-05-01
1           2014-05-01 2014-07-01
3           2014-07-01 2014-08-01
1           2014-08-01 2016-01-01

(5 row(s) affected)

但是,如果您添加了一些新的范围,将覆盖另一个范围(如
(6,'2014-07-15','2015-08-01')
),您应该更改该查询。

您可以发布您到目前为止尝试过的查询吗?如果年份(开始日期)=年份(结束日期),则开始日期其他日期添加(MM,DATEDIFF(MM,0,LAG(结束日期,1))结束(截止日期的订单)+1,0)结束为开始日期这是我如何尝试根据结束日期生成新的开始日期。任何情况下的条件都是我问题的临时解决方案。仔细观察日期及其价格。不知道是否有那么困难。价格从何而来您只发布了开始日期和结束日期如果您使用gener对于日期范围,这可能很难在单个查询中解决-这是“最少工作”的少数情况之一解决方案实际上是使用光标并遍历数据。例如,您不会说是否有人可以在以后将日期范围(例如
01-01-2000
添加到
01-01-2999
)中。此外,使用什么规则来决定哪个日期范围“获胜”-是否总是较短的日期范围、最高价格等?我认为只有当您有一个长周期和一些短周期时,它才会起作用。在其他情况下,您应该在cte的val部分更改条件
X           START_DATE END_DATE
----------- ---------- ----------
1           2014-01-01 2014-04-01
2           2014-04-01 2014-05-01
1           2014-05-01 2014-07-01
3           2014-07-01 2014-08-01
1           2014-08-01 2016-01-01

(5 row(s) affected)