在表中生成固定数量的行

Bri*_*ian 4 t-sql sql-server sql-server-2008

无法正确表达问题,因此无法搜索我想要的内容。我所需要的只是一个带有一列say guids的虚拟表,我将它用于其他目的。没有实际写相同的insert .. newID()n 次,想知道是否有一个优雅的解决方案。

类似的问题是如何用一个 int 列填充一个空白表,比如 1-n 个数字。

Row1: 1
Row2: 2
.......
Row100:100
Run Code Online (Sandbox Code Playgroud)

Aar*_*and 7

我建议使用基于集合的方法,而不是递归 CTE,从您知道已经有 100 多行的任何对象中提取。

--INSERT dbo.newtable(ID, GUID)
SELECT TOP (100) ROW_NUMBER() OVER (ORDER BY [object_id]), NEWID()
  FROM sys.all_columns ORDER BY [object_id];
Run Code Online (Sandbox Code Playgroud)

有关许多其他想法,请参阅本系列:


Ano*_*non 6

这种方法非常快。如果您需要从无到有生成数字表,这可能是可用的“最佳”方法。

WITH
t0(i) AS (SELECT 0 UNION ALL SELECT 0), --             2 rows
t1(i) AS (SELECT 0 FROM t0 a, t0 b),    --             4 rows
t2(i) AS (SELECT 0 FROM t1 a, t1 b),    --            16 rows
t3(i) AS (SELECT 0 FROM t2 a, t2 b),    --           256 rows
--t4(i) AS (SELECT 0 FROM t3 a, t3 b),  --        65,536 rows
--t5(i) AS (SELECT 0 FROM t4 a, t4 b),  -- 4,294,967,296 rows

n(i) AS (SELECT ROW_NUMBER() OVER(ORDER BY (SELECT 0)) FROM t3)
SELECT i FROM n WHERE i BETWEEN 1 AND 100
Run Code Online (Sandbox Code Playgroud)

关于性能:

  • 使用 SQL Server 2022,在 2016 年的 Xeon 机器上,SET STATISTICS TIME ON测量查询时间,我得到了这些数字:
    • (用t4t5注释掉),它在“0ms”内生成 256 行。
    • (未t4注释)它在 53 毫秒内生成 65,536 行。
    • t5在 中未注释INSERT FROM)它在大约 65 分钟内生成并插入了 40 亿行到TABLE磁盘上。
      • 每分钟 6600 万行,或者每秒大约 100 万行,太好了!

解释:

  • 第一个 CTEt0生成 2 行。
  • 每个后续 CTE 都会执行CROSS JOIN前一个 CTE 的操作;aCROSS JOIN笛卡尔积,它有效地对每个 CTE 步骤中的行数 进行平方。
    • 因此,t0通过t3意味着执行笛卡尔积三次,从而生成256 行 == 2 平方,平方,再次平方行。
    • SELECT 0 FROM t0 a, t0 b与 是一样的SELECT 0 FROM t0 AS a CROSS JOIN t0 AS b

请注意,结果从 开始,1而不是0因为ROW_NUMBER()从 开始1。从最外层查询中的0do开始。SELECT ( i - 1 ) FROM n


小智 5

你可以递归地做。

对于数字,例如:

WITH r AS (
    SELECT 1 AS n
    UNION ALL
    SELECT n+1 FROM r WHERE n+1<=100
)
SELECT * FROM r
Run Code Online (Sandbox Code Playgroud)

  • 不适用于 101 行及更多 - 默认 CTE 嵌套限制 (2认同)