数字辅助表是一个连续整数的数列,通常用来实现多种不同的查询任务。大多分两类:足够大物理数字表和表函数,前者可以称为静态的,后者可以称为动态且按需生产。
物理数字表
    物理数字表通常存在一个物理表,表记录相对足够大,相关的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. 使用Guava提供的transform批量转换

    实际开发了,为了快速查询,我们会把日期以Long类型的方式存储到数据库中,比如20000000000000L,但显示的时候,要完整的日期,即yyyy-MM-dd的格式显示. 这个时候,我们就可以使用C ...

  2. iOS instruments trace文件解析方案

    前言 已很少写文章,不过这次感觉有必要写一下.因为: 1. 这个方案通过debug逆向得来,很有参考意义. 2. iOS这方面资料非常少,做这块时,无论国内外,翻遍了google,baidu都没太多合 ...

  3. IOS Animation-Sprite Kit(一)基础

    介绍 Sprite Kit是IOS7开始引入的,是一个高效率渲染的2D图形框架.它与绘制图形的Core Graphics以及用来管理GUI元素动画属性的Core Animation不同,Sprite ...

  4. jQuery不支持hashchange事件?

    $(window) .bind( 'hashchange', onHashchange ) .trigger( 'hashchange' ); jQuery版本是1.9.1的,去源码里没找到hashc ...

  5. LINQ to Entities不识别方法***,因此该方法无法转换为存储表达式

    我的程序里有这么一段代码: order.OrderExpressInfo = (from oei in orderExpressRepository.Entities where oei.OrderI ...

  6. Netfilter/iptables的匹配方式及处理方法

    匹配方式: 匹配方式是netfilter筛选数据包的最基本单元. 内置的匹配方式: 1.接口的匹配方式: iptables -t filter -A FORWARD -i eth0 -o eth1 - ...

  7. fir.im Weekly - 600个 Android 开源项目汇总

    本期 Weekly 收集了一些热度资源,包含 Android.iOS 开发工具与源码分享,程序员也应该了解的产品运营.设计等 Tips ,希望对你有帮助. 600个Android开源项目汇总 勤劳的 ...

  8. Searching for a valid kernel header path... The path "" is not a valid path to the ***** kernel headers. Would you like to change it? [yes]

    在centos 6.5安装vmtools时候,解压包,mount挂载后,安装pl过程中报 这个问题,半天没有解决,google 后发现这样就行了 I installed the kernel-deve ...

  9. Java EE开发平台随手记1

    过完春节以来,一直在负责搭建公司的新Java EE开发平台,所谓新平台,其实并不是什么新技术,不过是将目前业界较为流行的框架整合在一起,做一些简单的封装和扩展,让开发人员更加易用. 和之前负责具体的项 ...

  10. 不同场景下 MySQL 的迁移方案

    一 目录 一 目录 二 为什么要迁移 三 MySQL 迁移方案概览 四 MySQL 迁移实战 4.1 场景一 一主一从结构迁移从库 4.2 场景二 一主一从结构迁移指定库 4.3 场景三 一主一从结构 ...