May be this:-DECLARE @MinYear int,@MaxYear intSELECT @MinYear=MIN(Year),@MaxYear=MAX(Year) FROM TableSELECT IDENTITY(int,1,1) AS ID, @MinYear + v.Number AS Year, q.Quarter INTO #CalendarFROM master..spt_values vCROSS JOIN (SELECT 'Q1' AS Quarter UNION ALL SELECT 'Q2' UNION ALL SELECT 'Q3' UNION ALL SELECT 'Q4')qWHERE v.type='p'AND @MinYear + v.Number <=@MaxYearDECLARE @Periodlist varchar(8000)SELECT @Periodlist=LEFT(pl.Periodlist,LEN(pl.Periodlist)-1)FROM (SELECT CAST(c.Year AS varchar(4))+c.Quarter+',' AS [text()] FROM #Calendar WHERE ID =@ID FOR XML PATH(''))pl(Periodlist)SET @Sql='SELECT m.ItemID,COALESCE('+REPLACE(@Periodlist,',',',0),COALESCE(') + ' FROM(SELECT CAST(c.Year AS varchar(4))+c.Quarter AS Period,t.ItemIDt.ValueFROM #Calendar cLEFT JOIN Table tON t.Year=c.YearAND c.Quarter=t.QtrWHERE c.ID <=@ID )mPIVOT (SUM(Value) FOR Period IN (['+ REPLACE(@Periodlist,',','],[') +']))p'EXEC (@Sql)