SQL Server 实现数字辅助表实例代码

数字辅助表是一个连续整数的数列,通常用来实现多种不同的查询任务。大多分两类:足够大物理数字表和表函数,前者可以称为静态的,后者可以称为动态且按需生产。

物理数字表

物理数字表通常存在一个物理表,表记录相对足够大,相关的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代码如下:

1 SELECT Num 2 FROM dbo.Nums; 3 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^2^L。 -- 例如:在5级就会得到4 294 967 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(1), (1)) AS LO(c)), L1 AS (SELECT 1 AS c FROM L0 AS T CROSS JOIN L0 AS T2), L2 AS (SELECT 1 AS c FROM L1 AS T CROSS JOIN L1 AS T2), L3 AS (SELECT 1 AS c FROM L2 AS T CROSS JOIN L2 AS T2), L4 AS (SELECT 1 AS c FROM L3 AS T CROSS JOIN L3 AS T2), L5 AS (SELECT 1 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 + 1) @bintLow + RowNum - 1 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^2^L。 -- 例如:在5级就会得到4 294 967 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(1), (1)) AS LO(c)), L1 AS (SELECT 1 AS c FROM L0 AS T CROSS JOIN L0 AS T2), L2 AS (SELECT 1 AS c FROM L1 AS T CROSS JOIN L1 AS T2), L3 AS (SELECT 1 AS c FROM L2 AS T CROSS JOIN L2 AS T2), L4 AS (SELECT 1 AS c FROM L3 AS T CROSS JOIN L3 AS T2), L5 AS (SELECT 1 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 - 1 AS Num FROM Nums ORDER BY RowNum ASC OFFSET 0 ROWS FETCH FIRST @bintHigh - @bintLow + 1 ROWS ONLY; GO

以函数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 有关书籍的作者)

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

时间: 2024-10-27 07:11:02

SQL Server 实现数字辅助表实例代码的相关文章

SQL Server 实现数字辅助表实例代码_MsSql

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

SQL Server 2008 R2——使用数字辅助表(master..spt_values)实现用计数字段对记录进行重复显示

原文:SQL Server 2008 R2--使用数字辅助表(master..spt_values)实现用计数字段对记录进行重复显示 =================================版权声明================================= 版权声明:原创文章 谢绝转载  请通过右侧公告中的"联系邮箱(wlsandwho@foxmail.com)"联系我 勿用于学术性引用. 勿用于商业出版.商业印刷.商业引用以及其他商业用途.       本文不定期修

在 SQL Server 中查询EXCEL 表中的数据遇到的各种问题

原文:在 SQL Server 中查询EXCEL 表中的数据遇到的各种问题 SELECT * FROM OpenDataSource( 'Microsoft.Jet.OLEDB.4.0','Data Source="D:\KK.xls";User ID=Admin;Password=;Extended properties=Excel 5.0')...[Sheet1$] 问题:消息 15281,级别 16,状态 1,第 1 行 SQL Server 阻止了对组件 'Ad Hoc Dis

SQL Server中统计每个表行数的快速方法

这篇文章主要介绍了SQL Server中统计每个表行数的快速方法,本文不使用传统的count()函数,因为它比较慢和占用资源,本文讲解的是另一种方法,需要的朋友可以参考下 我们都知道用聚合函数count()可以统计表的行数.如果需要统计数据库每个表各自的行数(DBA可能有这种需求),用count()函数就必须为每个表生成一个动态SQL语句并执行,才能得到结果.以前在互联网上看到有一种很好的解决方法,忘记出处了,写下来分享一下. 该方法利用了sysindexes 系统表提供的rows字段.rows

SQL Server 2005 查看数据库表的大小 按照表大小排列

(1)Question:尼玛一个数据库,动辄几十个G,伤不起啊,怎样才能知道当前数据库里面各个表的大小呢?以便将部分较大的数据库表中不容易被频繁访问的数据归档到历史表中,例如每天将一个自然年以前的数据放入历史表中.(2)Key:网上搜了一圈,关键字sp_spaceused (参见:http://msdn.microsoft.com/zh-cn/library/ms188776.aspx)(3)Sample:同时找到了一个示例(参见:http://www.linuxso.com/linuxxito

MySQL数字辅助表

最近在做一个活动签到的功能,每个用户每天签到,累计到一定次数,可以换一些奖品. 签到表的设计如下 CREATE TABLE `award_chance_history` ( `id` int(11) NOT NULL AUTO_INCREMENT, `awardActId` int(11) DEFAULT NULL COMMENT '活动id', `vvid` bigint(20) DEFAULT NULL COMMENT '用户id', `createtime` timestamp NOT N

清空SQL Server数据库中所有表数据的方法

原文:清空SQL Server数据库中所有表数据的方法 其实删除数据库中数据的方法并不复杂,为什么我还要多此一举呢,一是我这里介绍的是删除数据库的所有数据,因为数据之间可能形成相互约束关系,删除操作可能陷入死循环,二是这里使用了微软未正式公开的sp_MSForEachTable存储过程. 也许很多读者朋友都经历过这样的事情:要在开发数据库基础上清理一个空库,但由于对数据库结构缺乏整体了解,在删除一个表的记录时,删除不了,因为可能有外键约束,一个常见的数据库结构是一个主表,一个子表,这种情况下一般

SQL server 2008安装时出现实例失败问题?如下图,遇到这种情况怎么处理

问题描述 SQL server 2008安装时出现实例失败问题?如下图,遇到这种情况怎么处理 解决方案 实例名不能是数字开头,如同变量一样 解决方案二: 使用默认实例安装,安装后再设置

Angular.js 实现数字转换汉字实例代码_AngularJS

AngularJS 简介 AngularJS 是一个 JavaScript 框架.它可通过 <script> 标签添加到 HTML 页面. AngularJS 通过 指令 扩展了 HTML,且通过 表达式 绑定数据到 HTML. 下面通过本文给大家介绍Angular.js 实现数字转换汉字实例代码,具体代码如下所示: // 1.实现输入数字输出对应汉字,要求使用angularjs,不准使用$watch函数,for循环:提示:ng-change指令 <div ng-app="my