SQL Server 怎樣生成序列號(虛擬數字輔助表)


</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;  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM