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

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

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

执行后的查询结果如下:

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

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

 IF OBJECT_ID(N'dbo.ufn_GetNums2', N'IF') IS NOT NULL
BEGIN
DROP TABLE dbo.ufn_GetNums2;
END
GO --==================================
-- 功能: 获取指定范围的数字数列
-- 说明: 交叉最后层级的CTE得到的数据行:在L级(从0开始计数)得到的行的总数为2^^L。
-- 例如:在5级就会得到4 596行。5级的CTE提供了超过40亿的行。
-- 作者: XXX
-- 创建: yyyy-MM-dd
-- 修改: yyyy-MM-dd XXX 修改内容描述
--==================================
CREATE FUNCTION dbo.ufn_GetNums2
(
@bintLow BIGINT,
@bintHigh BIGINT
) RETURNS TABLE
AS
RETURN
WITH
L0 AS (SELECT c FROM (VALUES(), ()) AS LO(c)),
L1 AS (SELECT AS c FROM L0 AS T CROSS JOIN L0 AS T2),
L2 AS (SELECT AS c FROM L1 AS T CROSS JOIN L1 AS T2),
L3 AS (SELECT AS c FROM L2 AS T CROSS JOIN L2 AS T2),
L4 AS (SELECT AS c FROM L3 AS T CROSS JOIN L3 AS T2),
L5 AS (SELECT AS c FROM L4 AS T CROSS JOIN L4 AS T2),
Nums AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNum FROM L5) SELECT @bintLow + RowNum - AS Num
FROM Nums
ORDER BY RowNum ASC
OFFSET ROWS FETCH FIRST @bintHigh - @bintLow + ROWS ONLY;
GO

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

SELECT Num
FROM dbo.ufn_GetNums(, );
GO

执行后的查询结果如下:

 
博友如有其他更好的解决方案,也请不吝赐教,万分感谢。
 
参考清单列表
1、《Microsoft SQL Server 2012 High-Performance T-SQL Using Window Functions》 作者 Itzik Ben-Gan(美国)(SQL Server Inside 有关书籍的作者)

SQL Server数字辅助表的实现的更多相关文章

  1. SQL虚拟数字辅助表

    虚拟数字辅助表是一个整数序列,可以用来完成多种不同的任务,如生成日期跟时间值序列,及分裂值列表.要用查询逻辑产生一个大的整数序列,可以使用交叉连接(cross join). 交叉联接(cross jo ...

  2. SQL Server 怎样生成序列号(虚拟数字辅助表)

    </pre><pre name="code" class="sql">--生成一个"序列" 或者说生成一个" ...

  3. SQL Server数据库、表、数据类型基本概念

    一.SQL Server的数据存储结构 SQL Server是一个数据库管理系统,需要以有效方式存储高容量数据.要更好地理解SQL Server处理数据的方式,就需要了解数据的存储结构. 1.文件类型 ...

  4. SQL server 数据库用户表名称

    转自(http://blog.163.com/jlj_sk/blog/static/22579293200861422833924/) 取得SQL server 数据库中 所有用户表名称 select ...

  5. 使用Spark加载数据到SQL Server列存储表

    原文地址https://devblogs.microsoft.com/azure-sql/partitioning-on-spark-fast-loading-clustered-columnstor ...

  6. 在SQL SERVER中获取表中的第二条数据

    在SQL SERVER中获取表中的第二条数据, 思路:先根据时间逆排序取出前2条数据作为一个临时表,再按顺时排序在临时表中取出第一条数据 sql语句如下: select top 1 * from(se ...

  7. 显示 Sql Server 中所有表或表中行的信息

    在MSSQL中显示某个数据库中所有表或视图的信息: (以下语句为获取所有表信息,将绿色字"U"替换为"V"则获取所有视图信息.) SELECT sysobjec ...

  8. 快速查看SQL Server 中各表的数据量以及占用空间大小

    快速查看SQL Server 中各表的数据量以及占用空间大小. CREATE TABLE #T (NAME nvarchar(100),ROWS char(20),reserved varchar(1 ...

  9. Oracle\MS SQL Server Update多表关联更新

    原文:Oracle\MS SQL Server Update多表关联更新 一条Update更新语句是不能更新多张表的,除非使用触发器隐含更新.而表的更新操作中,在很多情况下需要在表达式中引用要更新的表 ...

随机推荐

  1. Blend 2015 教程 (一) 基础

    微软公司在Visual Studio 2015产品套件中作出了许多革命性的变更,包括.NET开源,.NET服务器端部分跨平台,推出向个人和小团队免费的社区版,移动应用开发部分跨平台支持,商店应用支持C ...

  2. 用JS识别各版本浏览器

    自昨天发了各浏览器内核介绍的随笔,就闲不住了,想直接写个JS来识别用户所用浏览器版本. 写着写着却发现很多坑爹的地方,比如IE10-的版本是依循常规支持attachEvent,但到了IE11,却只支持 ...

  3. Nim教程【十一】

    引用类型和指针类型 不同的引用可以只想和修改相同的内存单元 在nim中有两种引用方式,一种是追踪引用,另一种是非追踪引用 非追踪引用也就是指针,指向手动在内存中分配的对象: 追踪引用指向一个垃圾收集的 ...

  4. 自动更新Chromium

    Chromium 其实就是开发版本的Chrome, 即Chrome dev 版本.一般他的版本要比正式版的Chrome高两个及以上.比如正式版本现在是29,开发者版本已经是32了. 这表示很多新功能你 ...

  5. [我给Unity官方视频教程做中文字幕]beginner Graphics – Lessons系列之网格Meshes

    [我给Unity官方视频教程做中文字幕]beginner Graphics – Lessons系列之网格Meshes 本篇分享一下第5个已完工的视频,即<beginner Graphics – ...

  6. SQL——索引

    索引是根据表中一列或若干列按照一定顺序建立的列值与记录行之间的对应关系表.在数据库系统中建立索引主要有以下作用: l快速存取数据: l保证数据记录的唯一性: l实现表与表之间的参照完整性: l在使用O ...

  7. 为什么占位符可以防止sql注入?

    先看下面用占位符来查询的一句话 String sql = "select * from administrator where adminname=?"; psm = con.pr ...

  8. Redis学习笔记~Redis主从服务器,读写分离

    回到目录 Redis这个Nosql的存储系统一般会被部署到linux系统中,我们可以把它当成是一个数据服务器,对于并发理大时,我们会使用多台服务器充当Redis服务器,这时,各个Redis之间也是分布 ...

  9. 说说设计模式~适配器模式(Adapter)

    返回目录 之前和大家一起谈了工厂模式和单例模式,今天来看一下另一种非常常用的模式,它就是适配器模式,第一次看到这个模式是通过“张逸”老师的“设计之道”这篇文章,在这里表adapter讲的很透彻,今天把 ...

  10. lua的table表处理 及注意事项

    lua,一款很轻量级很nice很强大的脚本语言,做为lua中使用最为频繁的table表,在使用之时还是有颇多的好处与坑的: 下面是大牛 云风的一片关于lua table的blog,可使得对lua ta ...