• SQL Server数字辅助表的实现


        数字辅助表是一个连续整数的数列,通常用来实现多种不同的查询任务。大多分两类:足够大物理数字表和表函数,前者可以称为静态的,后者可以称为动态且按需生产。
    物理数字表
        物理数字表通常存在一个物理表,表记录相对足够大,相关的T-SQL代码如下:
     1 IF OBJECT_ID(N'dbo.Nums', 'U') IS NOT NULL
     2 BEGIN
     3     DROP TABLE dbo.Nums;
     4 END
     5 GO
     6  
     7 CREATE TABLE dbo.Nums 
     8 (
     9     Num INT NOT NULL,
    10     CONSTRAINT PK_U_CL_Nums_Num PRIMARY KEY CLUSTERED
    11     (
    12         Num ASC
    13     ) 
    14 );
    15 GO
    16  
    17 INSERT INTO dbo.Nums (Num)
    18 SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNum
    19 FROM master.dbo.spt_values;
    20 GO

    注意:如何填充物理数字表的方法很多,为了演示作用使用了一种。

    测试的T-SQL代码如下:
    1 SELECT Num
    2 FROM dbo.Nums;
    3 GO

    执行后的查询结果如下:

     
    表函数
        表函数实现使用交叉连接和CTE,SQL Server 2005和以上版本的T-SQL代码如下:
     1 IF OBJECT_ID(N'dbo.ufn_GetNums', N'IF') IS NOT NULL
     2 BEGIN
     3     DROP TABLE dbo.ufn_GetNums;
     4 END
     5 GO
     6  
     7 --==================================
     8 -- 功能: 获取指定范围的数字数列
     9 -- 说明: 交叉最后层级的CTE得到的数据行:在L级(从0开始计数)得到的行的总数为2^2^L。
    10 --       例如:在5级就会得到4 294 967 596行。5级的CTE提供了超过40亿的行。
    11 -- 作者: XXX
    12 -- 创建: yyyy-MM-dd
    13 -- 修改: yyyy-MM-dd XXX 修改内容描述
    14 --==================================
    15 CREATE FUNCTION dbo.ufn_GetNums
    16 (
    17     @bintLow BIGINT,
    18     @bintHigh BIGINT
    19 ) RETURNS TABLE
    20 AS
    21 RETURN 
    22     WITH
    23         L0 AS (SELECT c FROM (VALUES(1), (1)) AS LO(c)),
    24         L1 AS (SELECT 1 AS c FROM L0 AS T CROSS JOIN L0 AS T2),
    25         L2 AS (SELECT 1 AS c FROM L1 AS T CROSS JOIN L1 AS T2),
    26         L3 AS (SELECT 1 AS c FROM L2 AS T CROSS JOIN L2 AS T2),
    27         L4 AS (SELECT 1 AS c FROM L3 AS T CROSS JOIN L3 AS T2),
    28         L5 AS (SELECT 1 AS c FROM L4 AS T CROSS JOIN L4 AS T2),
    29         Nums AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNum FROM L5)
    30  
    31     SELECT TOP (@bintHigh - @bintLow + 1) @bintLow + RowNum - 1 AS Num
    32     FROM Nums
    33     ORDER BY RowNum ASC;
    34 GO

        SQL Server 2012增加了有关分页的新特性,相关的T-SQL代码如下:

     1 IF OBJECT_ID(N'dbo.ufn_GetNums2', N'IF') IS NOT NULL
     2 BEGIN
     3     DROP TABLE dbo.ufn_GetNums2;
     4 END
     5 GO
     6  
     7 --==================================
     8 -- 功能: 获取指定范围的数字数列
     9 -- 说明: 交叉最后层级的CTE得到的数据行:在L级(从0开始计数)得到的行的总数为2^2^L。
    10 --       例如:在5级就会得到4 294 967 596行。5级的CTE提供了超过40亿的行。 
    11 -- 作者: XXX
    12 -- 创建: yyyy-MM-dd
    13 -- 修改: yyyy-MM-dd XXX 修改内容描述
    14 --==================================
    15 CREATE FUNCTION dbo.ufn_GetNums2
    16 (
    17     @bintLow BIGINT,
    18     @bintHigh BIGINT
    19 ) RETURNS TABLE
    20 AS
    21 RETURN 
    22     WITH
    23         L0 AS (SELECT c FROM (VALUES(1), (1)) AS LO(c)),
    24         L1 AS (SELECT 1 AS c FROM L0 AS T CROSS JOIN L0 AS T2),
    25         L2 AS (SELECT 1 AS c FROM L1 AS T CROSS JOIN L1 AS T2),
    26         L3 AS (SELECT 1 AS c FROM L2 AS T CROSS JOIN L2 AS T2),
    27         L4 AS (SELECT 1 AS c FROM L3 AS T CROSS JOIN L3 AS T2),
    28         L5 AS (SELECT 1 AS c FROM L4 AS T CROSS JOIN L4 AS T2),
    29         Nums AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNum FROM L5)
    30  
    31     SELECT @bintLow + RowNum - 1 AS Num
    32     FROM Nums
    33     ORDER BY RowNum ASC
    34     OFFSET 0 ROWS FETCH FIRST @bintHigh - @bintLow + 1 ROWS ONLY;
    35 GO
    36  

    以函数ufn_GetNums为例,演示相关的效果。获取指定范围的数字序列的T-SQL代码如下:

    SELECT Num
    FROM dbo.ufn_GetNums(11, 20);
    GO

    执行后的查询结果如下:

     
    博友如有其他更好的解决方案,也请不吝赐教,万分感谢。
     
    参考清单列表
    1、《Microsoft SQL Server 2012 High-Performance T-SQL Using Window Functions》 作者 Itzik Ben-Gan(美国)(SQL Server Inside 有关书籍的作者)
  • 相关阅读:
    CF979D Kuro and GCD and XOR and SUM(01Trie)
    2020中国计量大学校赛题解
    CF16E Fish (状压dp)
    2017ccpc杭州站题解
    HDU6274 Master of Sequence(二分+预处理)
    CF899F Letters Removing(树状数组+二分)
    牛客 tokitsukaze and Soldier(优先队列+排序)
    HDU6268 Master of Subgraph(点分治)
    CF862E Mahmoud and Ehab and the function(二分)
    CF1108F MST Unification(生成树+思维)
  • 原文地址:https://www.cnblogs.com/dzy863/p/5080832.html
Copyright © 2020-2023  润新知