</pre><pre name="code" class="sql">--生成一個"序列" 或者說生成一個"虛擬數字輔助表"是擴展數據庫集合操作的重要途徑。其主要創建途徑一般是通過笛卡爾積法、系統表法(實質一般也是笛卡爾積法)、創建自定義函數法等方式。 --笛卡爾積法,先構建一個包含10行記錄的輔助表,選擇10行記錄主要是為了方便交叉連接時按照10進制擴展行數 WITH t1 AS ( SELECT 1 AS RN 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 NUM=ROW_NUMBER() OVER(ORDER BY a.RN) FROM T1 a,T1 b,T1 c,T1 d,T1 e,T1 f,T1 g --生成e10+8(一千萬)耗時01:12 --遞歸法,遞歸法另一用途是層次查詢遍歷各級節點;在實現各種復雜數學序列中亦有應用 --注意當遞歸次數過百時需加OPTION(MAXRECURSION 0)控制條件使數據庫不限定遞歸次數 WITH T1 AS ( SELECT 1 AS NUM UNION ALL SELECT T1.NUM+1 FROM T1 WHERE T1.NUM<10000000) SELECT NUM FROM T1 OPTION(MAXRECURSION 0) --生成e10+8(一千萬)耗時02:45 --系統表法,生成0-2047 SELECT number FROM master..spt_values WHERE type='p' SELECT TOP 10000000 NUM=ROW_NUMBER() OVER(ORDER BY GETDATE()) FROM syscolumns a,syscolumns b,syscolumns c --生成e10+8(一千萬)耗時01:16 --自定義函數法 -- definition of GetNums function, SQL Server 2012 version --注意生成的"虛擬數字輔助表"的列別名是"n" USE TSQL2012; IF OBJECT_ID('dbo.GetNums', 'IF') IS NOT NULL DROP FUNCTION dbo.GetNums; GO CREATE FUNCTION dbo.GetNums(@low AS BIGINT, @high AS BIGINT) RETURNS TABLE AS RETURN WITH L0 AS (SELECT c FROM (VALUES(1),(1)) AS D(c)), L1 AS (SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B), L2 AS (SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B), L3 AS (SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B), L4 AS (SELECT 1 AS c FROM L3 AS A CROSS JOIN L3 AS B), L5 AS (SELECT 1 AS c FROM L4 AS A CROSS JOIN L4 AS B), Nums AS (SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS rownum FROM L5) SELECT @low + rownum - 1 AS n FROM Nums ORDER BY rownum OFFSET 0 ROWS FETCH FIRST @high - @low + 1 ROWS ONLY; GO -- definition of GetNums function, pre-SQL Server 2012 version IF OBJECT_ID('dbo.GetNums', 'IF') IS NOT NULL DROP FUNCTION dbo.GetNums; GO CREATE FUNCTION dbo.GetNums(@low AS BIGINT, @high AS BIGINT) RETURNS TABLE AS RETURN WITH L0 AS (SELECT c FROM (VALUES(1),(1)) AS D(c)), L1 AS (SELECT 1 AS c FROM L0 AS A CROSS JOIN L0 AS B), L2 AS (SELECT 1 AS c FROM L1 AS A CROSS JOIN L1 AS B), L3 AS (SELECT 1 AS c FROM L2 AS A CROSS JOIN L2 AS B), L4 AS (SELECT 1 AS c FROM L3 AS A CROSS JOIN L3 AS B), L5 AS (SELECT 1 AS c FROM L4 AS A CROSS JOIN L4 AS B), Nums AS (SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS rownum FROM L5) SELECT TOP(@high - @low + 1) @low + rownum - 1 AS n FROM Nums ORDER BY rownum; GO -- test function --生成e10+8(一千萬)耗時01:18 SELECT n FROM dbo.GetNums(1, 10000000); --生成11至20的序列 SELECT n FROM dbo.GetNums(11, 20); --用函數生成日期序列,注意日期序列可由遞歸法直接生成,但日期類型必須是datetime,不能是date類型 DECLARE @start AS DATE = '20120201', @end AS DATE = '20120212'; SELECT DATEADD(day, n, @start) AS dt FROM dbo.GetNums(0, DATEDIFF(day, @start, @end)) AS Nums; GO DECLARE @start AS DATETIME2 = '2012-02-12 00:00:00.0000000', @end AS DATETIME2 = '2012-02-18 12:00:00.0000000'; SELECT DATEADD(hour, n*12, @start) AS dt FROM dbo.GetNums(0, DATEDIFF(hour, @start, @end)/12) AS Nums; GO [sql] view plain copy --T-SQL CREATE TABLE #NumberSequense(RN INT); DECLARE @i int; SET @i = 1 WHILE @i <= 1000 BEGIN INSERT INTO #NumberSequense SELECT @i; SET @i = @i + 1 END SELECT * FROM #NumberSequense ORDER BY RN DROP TABLE #NumberSequense;
--T-SQL CREATE TABLE #NumberSequense(RN INT); DECLARE @i int; SET @i = 1 WHILE @i <= 1000 BEGIN INSERT INTO #NumberSequense SELECT @i; SET @i = @i + 1 END SELECT * FROM #NumberSequense ORDER BY RN DROP TABLE #NumberSequense;