Ik heb een SQL Fiddle gemaakt van deze oplossing om mee te spelen.
In wezen creëert het een werktabel @Months en vervolgens voegt Cross dit alle jaren toe aan uw dataset. Dit levert een volledige lijst op van alle maanden voor alle jaren. Ik verliet toen de testgegevens in uw voorbeeld (tabel met de naam TEST - zie SQL-viool voor schema) terug in deze lijst om me een volledige lijst met waarden te geven voor de maanden waarin ze zijn. Het volgende probleem dat moest worden opgelost, was het gebruik van de waarden van de afgelopen maanden als die er deze maand nog niet waren. Daarvoor heb ik een gecorreleerde subquery gebruikt, d.w.z. ik heb tblValues alleen op zichzelf aangesloten waar het overeenkwam met de maximale rangorde van een rij die een waarde heeft. Dit geeft dan een complete resultatenset!
Als u op jaar\maand wilt filteren, kunt u dit toevoegen aan een WHERE-clausule net voor de laatste Order By.
Geniet ervan!
Testschema
CREATE TABLE TEST( Month tinyint, Year int, Value int)
INSERT INTO TEST(Month, Year, Value)
VALUES
(1,2013,100),
(4,2013,101),
(8,2013,102),
(2,2014,103),
(4,2014,104)
Zoekopdracht
DECLARE @Months Table(Month tinyint)
Insert into @Months(Month)Values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12);
With tblValues as (
select Rank() Over (ORDER BY y.Year, m.Month) as [Rank],
m.Month,
y.Year,
t.Value
from @Months m
CROSS JOIN ( Select Distinct Year from Test ) y
LEFT JOIN Test t on t.Month = m.Month and t.Year = y.Year
)
Select t.Month, t.Year, COALESCE(t.Value, t1.Value) as Value
from tblValues t
left join tblValues t1 on t1.Rank = (
Select Max(tmax.Rank)
From tblValues tmax
Where tmax.Rank < t.Rank AND tmax.Value is not null)
Order by t.Year, t.Month