El enfoque recursivo CTE - es realmente bueno.
ser sólo consciente de diferencia de rendimiento. Vamos a jugar con un millón de registros:
enfoque CTE recursiva. Duración = 14 segundos
declare @start int = 1;
declare @end int = 999999;
with numbers as
(
select @start as number
union all
select number + 1 from numbers where number < @end
)
select * from numbers option(maxrecursion 0);
Unión Todo + Cruz de Ingreso enfoque. Duración = 6 segundos
with N(n) as
(
select 1 union all select 1 union all select 1 union all
select 1 union all select 1 union all select 1 union all
select 1 union all select 1 union all select 1 union all select 1
)
select top 999999
row_number() over(order by (select 1)) as number
from
N n1, N n2, N n3, N n4, N n5, N n6;
Tabla Valor Constructor + Cruz de Ingreso enfoque. Duración = 6 segundos
(si SQL Server> = 2008)
with N as
(
select n from (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) t(n)
)
select top 999999
row_number() over(order by (select 1)) as number
from
N n1, N n2, N n3, N n4, N n5, N n6;
CTE recursiva + Cruz de Ingreso enfoque. :) Duración = 6 segundos
with N(n) as
(
select 1
union all
select n + 1 from N where n < 10
)
select top 999999
row_number() over(order by (select 1)) as number
from
N n1, N n2, N n3, N n4, N n5, N n6;
Obtendremos efecto más sorprendente si se intenta insertar el resultado en una variable de tabla:
INSERT INTO con enfoque recursivo CTE.Duración = 17 segundos
declare @R table (Id int primary key clustered);
with numbers as
(
select 1 as number
union all
select number + 1 from numbers where number < 999999
)
insert into @R
select * from numbers option(maxrecursion 0);
INSERT INTO con enfoque de Ingreso Cruz. Duración = 1 segundo
declare @C table (Id int primary key clustered);
with N as
(
select n from (values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) t(n)
)
insert into @C
select top 999999
row_number() over(order by (select 1)) as number
from
N n1, N n2, N n3, N n4, N n5, N n6;
Aquí es un interesante artículo sobre Tally Tables
PostgreSQL tiene una función GENERATE_SERIES() que hace precisamente esto. No sé qué otros DB podrían hacer algo similar. Probablemente pueda escribir un procedimiento almacenado para hacerlo si dicha función no existe en SQL Server. – Flimzy