SQL Server comment récupérer tous les nombres entre 2 nombres

J'ai 4 colonnes – Code, Montant, Début, Fin. Je voudrais prendre les entre les montants dans les colonnes de début et de fin et les changer en une colonne avec tous les résultats. Des suggestions sur la façon d'y parvenir? Merci.

Current Results: Code Amount Start End 1 5000 2015 2016 2 5000 2014 2016 3 20000 2012 2016 Desired Results: Code Amount StartEnd 1 5000 2015 1 5000 2016 2 5000 2014 2 5000 2015 2 5000 2016 3 20000 2012 3 20000 2013 3 20000 2014 3 20000 2015 3 20000 2016 

Vous pouvez utiliser un cte récursif pour générer tous les nombres entre le début minimum et la fin maximum et joindre sur les nombres générés.

 with cte as (select min(start) col,max(end) mx from tablename union all select col+1,mx from cte where col < mx) select t.code,t.amount,c.col from cte c join tablename t on c.col between t.start and t.end 

ou plus simplement

 with cte as (select id,amount,start startend,end from tablename union all select id,amount,start+1,end from cte where start<end) select id,amount,startend from cte order by 1,3 

Une autre option est un UDF. J'utilise ce TVF pour générer des gammes dynamics

 Declare @YourTable table (Code int, Amount int, Start int , [End] int) Insert into @YourTable values (1,5000 ,2015,2016), (2,5000 ,2014,2016), (3,20000,2012,2016) Select A.Code ,A.Amount ,StartEnd = cast(B.RetVal as int) From @YourTable A Cross Apply (Select * from [dbo].[udf-Range-Number](A.Start,A.[End],1)) B 

Résultats

 Code Amount StartEnd 1 5000 2015 1 5000 2016 2 5000 2014 2 5000 2015 2 5000 2016 3 20000 2012 3 20000 2013 3 20000 2014 3 20000 2015 3 20000 2016 

La fonction

 CREATE FUNCTION [dbo].[udf-Range-Number] (@R1 money,@R2 money,@Incr money) Returns Table Return ( with cte0(M) As (Select cast((@R2-@R1)/@Incr as int)), cte1(N) As (Select 1 From (Values(1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N(N)), cte2(N) As (Select Top (Select M from cte0) Row_Number() over (Order By (Select NULL)) From cte1 a,cte1 b,cte1 c,cte1 d,cte1 e,cte1 f,cte1 g,cte1 h ) Select RetSeq=1,RetVal=@R1 Union All Select N+1,(N*@Incr)+@R1 From cte2 ) /* Max 100 million observations -- Syntax: Select * from [dbo].[udf-Range-Number](0,4,0.25) */ 

Je ne suis pas sûr que cela fonctionne sur SQL 2008, mais voici un CTE:

 ;with sel_cte as ( select Code, Amount, start StartEnd from @tblTest t union all select t.code, t.amount, c.StartEnd + 1 StartEnd from sel_cte c inner join @tblTest t on t.code = c.code where c.StartEnd + 1 <= [end] ) select * from sel_cte order by Code, StartEnd 

Remarque: remplacez @tblTest par le nom de la table.

Vous pouvez interroger comme ça

 SELECT c.code, c.amount, f.yr FROM #code c CROSS APPLY fn_yearslist(c.startyr, c.endyr) f 

fonction que vous pouvez créer comme ça

 CREATE FUNCTION fn_yearslist (@startyear int, @endyear int) RETURNS @t TABLE ( yr int ) AS BEGIN WHILE (@startyear <= @endyear) BEGIN INSERT INTO @t (yr) VALUES (@startyear) SET @startyear += 1 END RETURN END 

Si les exigences vous permettent d'avoir SEULEMENT des numéros successifs (comme 2014, 2015, puis 2016, etc.) alors l'approche ci-dessus (cte) fonctionnerait bien. Cependant, si ce n'est pas le cas, vous pouvez créer une autre table temporaire (disons des nombres ayant une colonne) avec des nombres successifs de ce que vous voulez que le résultat sorte, comme.

 Number 2014 2015 2016 2018 <-- Missing 2017 and jumping on 2018 2019 

Et puis utilisez une jointure à droite pour get des résultats dans la série progressive avec une requête similaire à celle ci-dessous.

 select Code, StartEnd, Amount from numbers right join inputs on number between Start and End