我有一个如下表格,其中列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
我怎样才能做到这一点?
答案 0 :(得分:1)
选中此项,如果您满意,请点击+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)
答案 1 :(得分:0)
;WITH cte AS (
SELECT *
FROM (VALUES
(1, '2014-01-01', '2016-01-01'),
(2, '2014-04-01', '2014-05-01'),
(3, '2014-07-01', '2014-08-01')
) as t(X, [START_DATE], [END_DATE])
)
,dates AS (
SELECT ROW_NUMBER() OVER ( ORDER BY d.[Date] ) as r,
d.[Date]
FROM (
SELECT c.START_DATE as [Date] FROM cte c
UNION
SELECT c.END_DATE as [Date] FROM cte c
) as d)
SELECT MAX(c.X) AS X,
d.[Date] AS [START_DATE],
d1.[Date] AS [END_DATE]
FROM dates d
INNER JOIN dates d1 ON d.r = d1.r-1
LEFT JOIN cte c ON d.[Date] BETWEEN c.START_DATE and c.END_DATE AND d1.[Date] BETWEEN c.START_DATE and c.END_DATE
GROUP BY d.[Date], d1.[Date]
结果:
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')
),你应该改变那个查询。