我有两种不同的情景。在第一个场景中,我需要类似的东西:
create table test
(
ItemID int,
ItemStartDate datetime,
ItemEndDate datetime,
itemType varchar(100)
)
表test
:
ItemID ItemStartDate ItemEndDate itemType
------ ------------- ----------- --------
item_1 1/1/2011 3/2/2011 value A
item_1 3/3/2011 12/31/2011 value A
item_2 1/3/2011 12/31/2011 value B
它应该只显示两条记录:
ItemID ItemStartDate ItemEndDate itemType
------ ------------- ----------- --------
item_1 1/1/2011 12/31/2011 value A
item_2 1/1/2011 12/31/2011 value B
情景2。 在这里,我想将数据值拆分为单独的年份,如果它是多年的话。
表test
create table #Scenario_2
(
ItemID int,
priceStartDate datetime,
priceEndDate datetime,
price int
)
item startdate enddate value
---- --------- ---------- -----
11 1/1/2011 5/4/2013 500
12 7/1/2013 11/12/2013 600
它应该显示为
item startdate enddate value
---- --------- ---------- -----
11 1/1/2011 12/31/2011 500
11 1/1/2012 12/31/2012 500
11 1/1/2013 5/4/2013 500
12 7/1/2013 11/12/2013 600
请告知我如何实现这一目标。
答案 0 :(得分:1)
试试这个。从你的问题来看,这就是我所理解的!!
SCENARIO 2
----------
CREATE TABLE #datt
(
itemid int,startd DATE,endat DATE,price int
)
INSERT INTO #datt
VALUES (11,'2011-01-01','2013-05-04',500),
(12,'2013-7-1','2013-11-12',600)
;WITH cte
AS (SELECT itemid,
startd st,
case when year(endat)<> YEAR(startd) then Dateadd(yy, Year(startd) - 1899, -1)
else endat end ed,price
FROM #datt
UNION ALL
SELECT a.itemid,
Dateadd(yy, 1, st),
CASE
WHEN Dateadd(yy, 1, ed) > b.endat THEN b.endat
ELSE Dateadd(yy, 1, ed)
END,a.price
FROM cte a
JOIN #datt b
ON a.itemid = b.itemid
AND a.ed < b.endat)
SELECT *
FROM cte order by itemid,st
答案 1 :(得分:0)
对于scenario1,您可以看到this answer。
对于scenario2,还可以引用similar answer。
但你的问题可以像这样简化:
with dates as
(
select number,cast(ltrim(number*10000+1231) as date) as dt
from master..spt_values
inner join
(select min(year(startdate)) as s_year
,max(year(enddate)) as e_year
from Scenario_2) as y
on number between y.s_year and y.e_year AND TYPE='P'
)
select
s.item
,case when year(dt) = year(startdate)
then startdate
else dateadd(year,-1,dateadd(day,1,dt)) end --or cast(ltrim(year(dt)*10000+101) as date)
,case when year(dt) = year(enddate)
then enddate
else dt end
,s.value
from
Scenario_2 s
inner join
dates d
on
d.number between year(s.startdate) and year(s.enddate)