志铭-2023年2月20日 22:50:32

0.永久性的连续数字表

使用循环可以快速创建一个Nums真实的表Nums

IF OBJECT_ID('dbo.Nums') IS NOT NULL
DROP TABLE dbo.Nums; CREATE TABLE dbo.Nums (n INT NOT NULL PRIMARY KEY); DECLARE @i INT = 1;
WHILE @i < 100
BEGIN
INSERT INTO dbo.Nums (n) VALUES (@i);
SET @i = @i + 1;
END;
SELECT * FROM dbo.Nums;

其实还有其他一些产生日志比较小,速度更快的方式创建连续数字表,但是没有必要,因为创建一个真实表,这个sql操作只需要执行一次。


1.使用系统表:master..spt_values

使用master..spt_values表中的number字段,可快速获取0-2047之间的连续数字

SELECT number FROM  master..spt_values WHERE	 type='p'

2.使用递归CTE

使用递归的方式创建数字

该方法相对较慢,但是SQL语句简洁明了

DECLARE @n AS BIGINT;
SET @n=1000000;
WITH Nums AS
(
SELECT 1 AS n
UNION ALL
SELECT n+1 FROM Nums WHERE n<@n
)
SELECT * FROM Nums OPTION(MAXRECURSION 0)--默认递归次数为100,这里设置取消递归次数限制

3.使用0-9乘以量级交叉连接

首先使用VALUES构造一个0-9的虚拟表

VALUES(0),(1), (2), (3), (4), (5), (6), (7), (8), (9)

个位数、十位数、百位数交叉链接构成1-1000

若是需要更多连续数字,则按照相同逻辑进行更多次的交叉连接

这里我使用表变量进行示例:

DECLARE @Nums TABLE(n INT);
INSERT INTO @Nums
SELECT * FROM(VALUES(0),(1), (2), (3), (4), (5), (6), (7), (8), (9)) AS T1(n);
SELECT T1.n+1+T2.n*10+T3.n*100 AS n FROM @Nums AS T1 CROSS JOIN @Nums AS T2 CROSS JOIN @Nums AS T3
ORDER BY n

4.使用2的次幂和CTE生成和交叉链接 创建表值函数

通过交叉连接生成大量的记录,然后取Row_Number(注意这里是使用Row_Number来获取连续的数字)

这里的原理就是((((2^2)^2)^2)^2)^2=4294967296,这个数字已经足够大足够我们使用了

这里我们创建一个表值函数GetNums

注1:这里sql server不是先生成4294967296行数据 ,在筛选出我们需要的。而是根据我们的最大参数生成记录,所以这里没有性能上的问题

注2:这个SQL函数来源于:《Microsoft SQL Server 2008技术内幕:T-SQL查询:6.4数字辅助表》


IF OBJECT_ID('dbo.GetNums') IS NOT NULL DROP FUNCTION dbo.GetNums;
GO
CREATE FUNCTION dbo.GetNums(@startNum AS BIGINT, @endNum 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 CROSS JOIN L0 AS B),
L2 AS (SELECT 1 AS c FROM L1 CROSS JOIN L1 AS B),
L3 AS (SELECT 1 AS c FROM L2 CROSS JOIN L2 AS B),
L4 AS (SELECT 1 AS c FROM L3 CROSS JOIN L3 AS B),
L5 AS (SELECT 1 AS c FROM L4 CROSS JOIN L4 AS B),
Nums AS (SELECT ROW_NUMBER() OVER (ORDER BY(SELECT NULL)) AS rownum FROM L5)
SELECT @startNum+rownum-1 AS n
FROM Nums
ORDER BY rownum OFFSET 0 ROWS FETCH FIRST @endNum-@startNum+1 ROWS ONLY; --测试返回1到100
SELECT * FROM dbo.GetNums(1,100)

5.数字辅助表使用情形

数字辅助表常常用于获取连续时间点

  • 获取某一天的24个小时
SELECT DATEADD(HH, number, '2023-02-20 00:00') AS OneDay
FROM master..spt_values
WHERE type='P' AND DATEDIFF(HH, DATEADD(HH, number, '2023-02-20 00:00'), '2023-02-20 23:00')>=0; --结果
OneDay
-----------------------
2023-02-20 00:00:00.000
2023-02-20 01:00:00.000
2023-02-20 02:00:00.000
2023-02-20 03:00:00.000
……
2023-02-20 20:00:00.000
2023-02-20 21:00:00.000
2023-02-20 22:00:00.000
2023-02-20 23:00:00.000 (24 行受影响)
  • 获取1994年1月1号到今天的每月的数据列:
SELECT CONVERT(VARCHAR(7), DATEADD(MONTH, number, '1994-01-01'), 23) AS MonthNo
FROM master..spt_values
WHERE type='p' AND number<=DATEDIFF(MONTH, '1994-01-01', GETDATE()); --小于指定日期到当前的所有月份 --结果:
MonthNo
-----------------
1994-01
1994-02
1994-03
1994-04
……
2022-12
2023-01
2023-02 (349 行受影响)
  • 获取2022年1月1日对今天的每天的数据列
SELECT CONVERT(VARCHAR(100), DATEADD(DAY, number, '2022-01-01'), 23) AS DayNo
FROM master..spt_values
WHERE type='p' AND number<=DATEDIFF(DAY, '2022-01-01', GETDATE()); --结果
DayNo
------------------
2022-01-01
2022-01-02
2022-01-03
2022-01-04
2022-01-05
……
2023-02-15
2023-02-16
2023-02-17
2023-02-18
2023-02-19
2023-02-20 (416 行受影响)
  1. 取两个字符串中重复的字符
DECLARE @text1 VARCHAR(100) ='十年我们,十年前我们在一起';
DECLARE @text2 VARCHAR(100) ='十年他们,十年后我们又重聚在一起';
SELECT SUBSTRING(@text2, number, 1) AS value
FROM master..spt_values
WHERE type='p' AND number<=LEN(@text2)AND CHARINDEX(SUBSTRING(@text2, number, 1), @text1)>0; --结果
value
-----



,






起 (11 行受影响)

6.参考

T-SQL——数字辅助表的更多相关文章

  1. SQL Server数字辅助表的实现

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

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

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

  3. SQL虚拟数字辅助表

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

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

    =================================版权声明================================= 版权声明:原创文章 谢绝转载  请通过右侧公告中的“联系邮 ...

  5. 使用CTE生成辅助表(数字或时间)等

    数字辅助表: , ;WITH Digital_Rangs(Digital) AS ( SELECT @start_digital UNION ALL FROM [Digital_Rangs] WHER ...

  6. 虚拟数字存储表——SQLServer2012可高用

    窗口函数之虚拟数字辅助表 数字辅助表是一个整数序列,可以用它来完成多种不同的查询任务.数字表有很多任务,如生成日期和时间值序列,及分裂值列表.通常,建议在数据库中保存这样一个永久表,并填充尽可能多的数 ...

  7. [SQL]SQL Server数据表的基础知识与增查删改

    SQL Server数据表的基础知识与增查删改 由张晨辉(学生) 于19天 前发表 | 阅读94次 一.常用数据类型 .整型:bigint.int.smallint.tinyint .小数:decim ...

  8. ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小 错误分析

    目录(?)[+] 1. 问题起因 最近在进行Oracle的一些操作时,总会遇到这个错误:  ORA-06502: PL/SQL: 数字或值错误 :  字符串缓冲区太小,错误如下: ORA-00604: ...

  9. 编写SQL的辅助工具

    原文:编写SQL的辅助工具 今天在同事的帮助下,下载了一个工具:ApexSQL edit,可能是我孤陋寡闻,不知道还有这样的好工具,它可以在我键入SQL时,帮助我提示表的名称和列名称.还可以帮助我格式 ...

  10. mysql生成日期的辅助表

    为了解决mysql按日期分组查询统计的时候,没有数据补0.可以生成连续的时间表格来辅助查询* 生成按天的数据 * 每一个小时为一个分段 生成如下辅助表 *代码如下 CREATE TABLE num ( ...

随机推荐

  1. 学习ASP.NET Core Blazor编程系列十四——修改

    学习ASP.NET Core Blazor编程系列一--综述 学习ASP.NET Core Blazor编程系列二--第一个Blazor应用程序(上) 学习ASP.NET Core Blazor编程系 ...

  2. static_cast和dynamic_cast

    C++的强制类型转换,除了继承自C语言的写法((目标类型)表达式)之外,还新增了4个关键字,分别是:static_cast.dynamic_cast.const_cast和reinterpret_ca ...

  3. ORM数据增删改查 django请求生命周期 django路由层 反向解析

    目录 可视化界面之数据增删改查 补充 1.建表 2.数据展示功能 3.数据添加功能 4.数据编辑功能 5.数据删除功能 django请求生命周期流程图 crsf wsgirel 与 uwsgi ngi ...

  4. Qt网络编程-从0到多线程编程

    网络编程开发 1.简介 两个协议,一个是TCP协议,一个是UDP协议 先说TCP: TCP的话,服务器端需要端口监听,直到有客户端进行连接发送过来请求数据,然后客户端根据请求数据进行应答,之后就算tc ...

  5. Mysql-delete语句

    ` 点击查看代码 删除2天之前的所有数据 delete From lkt_files_record where DATE(add_time) <= DATE(DATE_SUB(NOW(),INT ...

  6. STM32与PS2的无线通信和相关函数介绍

    PS2采用SPI通信协议 源码和参考文件获取:https://github.com/Sound-Sleep/PS2_Based_On_STM32 接收器接口 DI:手柄->主机,时钟的下降沿传送 ...

  7. [常用工具] PyAutoGUI使用教程

    PyAutoGUI使用教程 目录 PyAutoGUI使用教程 1 基础知识 2 一般函数 3 故障保险 4 鼠标函数 4.1 鼠标移动 4.2 鼠标拖动 4.3 鼠标单击 4.4 鼠标滚动 4.5 鼠 ...

  8. [编程基础] C++多线程入门3-小心地将参数传递给线程

    原始C++标准仅支持单线程编程.新的C++标准(称为c++11或c++0x)于2011年发布.在c++11中,引入了新的线程库.因此运行本文程序需要C++至少符合c++11标准. 文章目录 3 小心地 ...

  9. 行为型模式 - 观察者模式Observer

    学习而来,代码是自己敲的.也有些自己的理解在里边,有问题希望大家指出. 有一个大佬视频中提过一个案例,我觉得很棒:遥闻深巷中犬吠,边有妇人惊觉欠伸,其夫呓语.继而儿醒,大啼.夫亦醒. 模式的定义与特点 ...

  10. 结构型模式 - 享元模式Flyweight

    学习而来,代码是自己敲的.也有些自己的理解在里边,有问题希望大家指出. 更像是单例模式 + 简单工厂模式 享元模式的定义与特点 享元(Fiyweight)模式的定义:运用共享技术来有效的支持大量细粒度 ...