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)
我建议使用基于集合的方法,而不是递归 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)
有关许多其他想法,请参阅本系列:
这种方法非常快。如果您需要从无到有生成数字表,这可能是可用的“最佳”方法。
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)
关于性能:
SET STATISTICS TIME ON测量查询时间,我得到了这些数字:
t4和t5注释掉),它在“0ms”内生成 256 行。t4注释)它在 53 毫秒内生成 65,536 行。t5在 中未注释INSERT FROM)它在大约 65 分钟内生成并插入了 40 亿行到TABLE磁盘上。
解释:
t0生成 2 行。CROSS JOIN前一个 CTE 的操作;aCROSS JOIN是笛卡尔积,它有效地对每个 CTE 步骤中的行数
进行平方。
请注意,结果从 开始,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)