有没有办法在不创建表的情况下选择特定行数。例如如果我使用以下内容:
SELECT 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
它会给我10个,我想要10个新行。
由于
答案 0 :(得分:29)
您可以使用recursive 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);
答案 1 :(得分: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
答案 2 :(得分: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
答案 3 :(得分: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);
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;
表值构造函数+交叉连接方法。持续时间= 6秒
(如果SQL Server&gt; = 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 +交叉连接方法。 :)持续时间= 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;
如果我们尝试将结果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);
使用交叉连接方法插入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;
这是一篇关于Tally Tables
的有趣文章答案 4 :(得分:4)
SELECT 1
UNION
SELECT 2
UNION
...
UNION
SELECT 10 ;
答案 5 :(得分:2)
使用PIVOT(在某些情况下会有点矫枉过正)
DECLARE @Items TABLE(a int, b int, c int, d int, e int);
INSERT INTO @Items
VALUES(1, 2, 3, 4, 5)
SELECT Items
FROM @Items as p
UNPIVOT
(Items FOR Seq IN
([a], [b], [c], [d], [e]) ) AS unpvt
答案 6 :(得分:1)
使用spt_values表:
SELECT TOP (1000) n = ROW_NUMBER() OVER (ORDER BY number)
FROM [master]..spt_values ORDER BY n;
或者,如果所需的值小于1k:
SELECT DISTINCT n = number FROM master..[spt_values] WHERE number BETWEEN 1 AND 1000;
这是内部存储过程用于各种目的的表。它在网上的使用似乎非常普遍,即使它没有文档,不受支持,它可能有一天消失,因为它只包含一组有限的,非唯一的和非连续的值。 SQL Server 2008 R2中共有2,164个唯一值和2,508个值; 2012年有2,167个独特和2,515个。这包括重复,负值,即使使用DISTINCT,一旦超出数字2,048,就会有很多空白。因此,解决方法是使用
ROW_NUMBER()
根据表中的值从1开始生成连续序列。
此外,为了提供超过2k记录的更多值,您可以将表连接到自身,但在通常情况下,该表本身就足够了。
性能方面,它不应该太糟糕(生成一百万条记录,我的笔记本电脑需要10秒钟),并且查询非常容易阅读。
来源:http://sqlperformance.com/2013/01/t-sql-queries/generate-a-set-1
答案 7 :(得分:0)
;WITH nums AS
(SELECT 1 AS value
UNION ALL
SELECT value + 1 AS value
FROM nums
WHERE nums.value <= 99)
SELECT *
FROM nums