SQL选择没有表的'n'记录

Jam*_*mes 15 sql t-sql sql-server

有没有办法在不创建表的情况下选择特定数量的行.例如,如果我使用以下内容:

SELECT 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Run Code Online (Sandbox Code Playgroud)

它会给我10个跨越,我想要10个新行.

谢谢

Dav*_*kle 31

您可以使用递归CTE在T-SQL中生成任意数字序列,如下所示:

DECLARE @start INT = 1;
DECLARE @end INT = 10;

WITH numbers AS (
    SELECT @start AS number
    UNION ALL
    SELECT number + 1 
    FROM  numbers
    WHERE number < @end
)
SELECT *
FROM numbers
OPTION (MAXRECURSION 0);
Run Code Online (Sandbox Code Playgroud)


Cri*_*tiC 18

如果您有固定的行数,可以尝试:

SELECT 1
UNION
SELECT 2
UNION
SELECT 3
UNION
SELECT 4
UNION
SELECT 5
UNION
SELECT 6
UNION
SELECT 7
UNION
SELECT 8
UNION
SELECT 9
UNION
SELECT 10
Run Code Online (Sandbox Code Playgroud)


Jon*_*ton 7

如果你需要一个长列表,这是一个很好的方法(所以你不需要很多UNION语句:

WITH CTE_Numbers AS (
    SELECT n = 1
    UNION ALL
    SELECT n + 1 FROM CTE_Numbers WHERE n < 10 
)
SELECT n FROM CTE_Numbers
Run Code Online (Sandbox Code Playgroud)


Vad*_*oda 7

递归CTE方法 - 非常好.

要意识到性能差异.让我们玩一百万条记录:

递归CTE方法.持续时间= 14秒

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);
Run Code Online (Sandbox Code Playgroud)

Union All + Cross Join方法.持续时间= 6秒

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;
Run Code Online (Sandbox Code Playgroud)

表值构造函数+交叉连接方法.持续时间= 6秒

(如果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;
Run Code Online (Sandbox Code Playgroud)

递归CTE +交叉连接方法.:)持续时间= 6秒

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;
Run Code Online (Sandbox Code Playgroud)

如果我们尝试将结果INSERT到表变量中,我们将获得更多惊人的效果:

使用递归CTE方法插入INTO.持续时间= 17秒

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);
Run Code Online (Sandbox Code Playgroud)

使用交叉连接方法插入INTO.持续时间= 1秒

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;
Run Code Online (Sandbox Code Playgroud)

这是一篇关于Tally Tables的有趣文章