Jeg har oprettet en SQL Fiddle af denne løsning, som du kan lege med.
I det væsentlige opretter den en arbejdstabel @Måneder, og derefter slutter Cross sig til dette vil alle år i dit datasæt. Dette giver en komplet liste over alle måneder for alle år. Jeg forlod derefter at slutte mig til testdataene i dit eksempel (tabel med navnet TEST - se SQL-violin for skema) tilbage til denne liste for at give mig en komplet liste med værdier for de måneder, der har dem. Det næste problem at overvinde var at bruge de sidste måneders værdier, hvis denne måned ikke havde nogen. Til det brugte jeg en korreleret underforespørgsel, dvs. sluttede kun tblValues tilbage til sig selv, hvor den matchede den maksimale rangering af en række, som har en værdi. Dette giver så et komplet resultatsæt!
Hvis du vil filtrere efter år\måned, kan du tilføje dette i en WHERE-klausul lige før den endelige Order By.
God fornøjelse!
Testskema
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)
Forespørgsel
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