巧用spt_values解决SQL中的连续日期问题

简介: SQL数据库开发

spt_values是什么

spt_values是SQL Server新增的一个系统表,表里面都是一些枚举数据。我们可以通过如下查询语句来查看里面的数据


select * from master..spt_values


(因为该表属于系统数据库master下面,所以通常在表名前面添加库名master)

结果为:

50.jpg                                    (记录较多,只截取部分记录)

spt_values连续记录但是通常我们使用的是Type='P'的数据记录,这些记录是一组从0开始,2047为止的连续整数,具体如下:

select * from master..spt_values wheretype='P'


结果为:

51.jpg

                               (记录较多,只截取部分记录)

我们经常使用的就是number列,通过该列我们可以生成很多连续的记录,包括连续的日期,例如每天的24小时,每个月的每天,每年的12个月等等。

生成每天的24小时我们只需要指定开始和结束时间,就可以生成该时间段的连续小时了,这里从0点到23点。

SELECT

 SUBSTRING(CONVERT(CHAR(32),

 DATEADD(HH,number,CONCAT('2021-01-05',' ', '00:00')),120),1,16) AS GroupDay

FROM

 master..spt_values

WHERETYPE = 'P'

ANDDATEDIFF(HH,DATEADD(HH,number,

CONCAT('2021-01-05',' ', '00:00')),

CONCAT('2021-01-05',' ', '23:00'))>=0

结果为:

                                  52.jpg

                            (完整的有24条记录,这里只截取前几条)


生成每月的每天

我们只需要指定开始和结束日期,就可以生成该日期段的连续天了,这里从1月1日到1月31日。

SELECT

 CONVERT(NVARCHAR(10), DATEADD(DAY, number, '2021-01-01'),120) AS GroupDay

FROM

 master..spt_values

WHERETYPE = 'P'

ANDnumber <= DATEDIFF(DAY, '2021-01-01', '2021-01-31')


结果为:

                                                  53.jpg

                               (完整的有31条记录,这里只截取前几条)


生成每年的每月

我们只需要指定开始和结束月份,就可以生成该月份段的连续月了,这里从1月到12月。

SELECT

 SUBSTRING(CONVERT(NVARCHAR(10), DATEADD(MONTH, number, '2021-01-01'),120),1,7) AS GroupMonth

FROM

 master..spt_values

WHERETYPE = 'P'  

ANDnumber <= DATEDIFF(MONTH, '2021-01-01', '2021-12-01')


结果为:

                                                           54.jpg


spt_values应用实例

有如下一张表Test

55.jpg

要求:显示1月份所有日期的DataValue值,如果没有值的,就显示为0。
分析:我们数据库中只存储了4条数据,这时候我们可以利用SQL的表spt_values来实现。
解法:

SELECTDATEADD(DAY, number, CONVERT(DATETIME, '2021-01-01')) [DataTime],

      ISNULL(DataValue,0) DataValue

FROM master..spt_values

   LEFTJOINTest

       ONDATEADD(DAY, number, CONVERT(DATETIME, '2021-01-01')) = [DataTime]

WHEREtype = 'P'

     ANDnumber

     BETWEEN0ANDDATEDIFF(DAY, '2021-01-01', DATEADD(MONTH, 1, '2021-01-01'))-1;


结果为:

                 56.jpg

                         (完整的有31条记录,这里只截取前几条)

以上就是spt_values的一些用法,当然它不止在连续日期上的应用,只要是连续数字的问题,均可关联spt_values来解决。


相关文章
|
6月前
|
SQL BI 数据库
达梦(DM) SQL日期操作及分析函数
讲述DM 数据库中如何实现各种日期相关的运算以及如何利用分析函数 lead() over() 进行范围问题的处理
|
6月前
|
SQL Serverless 数据库
|
SQL 分布式计算 Unix
阿里云-DataWorks- ODPS SQL开发3-日期与字符、数学运算、聚合函数函数
阿里云-DataWorks- ODPS SQL开发3 本文主要讲解日常大量会接触到的一些常用的日期与字符、数学运算、聚合函数函数。
|
25天前
|
SQL 关系型数据库 MySQL
sql查询指定日期前n天数据
sql查询指定日期前n天数据
|
4月前
|
SQL 自然语言处理 数据挖掘
「SQL面试题库」 No_115 按日期分组销售产品
「SQL面试题库」 No_115 按日期分组销售产品
|
4月前
|
SQL 数据挖掘 数据处理
「SQL面试题库」 No_82 报告系统状态的连续日期
「SQL面试题库」 No_82 报告系统状态的连续日期
|
4月前
|
SQL 数据挖掘 数据处理
「SQL面试题库」 No_72 指定日期的产品价格
「SQL面试题库」 No_72 指定日期的产品价格
|
9月前
|
SQL
SQL技巧:构建一个包含过去30天日期的虚拟表
SQL技巧:构建一个包含过去30天日期的虚拟表
85 0
|
5月前
|
SQL Oracle 关系型数据库
Greenplum【SQL 01】通过 timestamp 类型字段值实现数据的日期时段筛选+时间时段筛选(跨天时段及不跨天时段SQL详情)
Greenplum【SQL 01】通过 timestamp 类型字段值实现数据的日期时段筛选+时间时段筛选(跨天时段及不跨天时段SQL详情)
41 0
|
SQL Oracle 关系型数据库
【SQL开发实战技巧】系列(二十一):数据仓库中时间类型操作(进阶)识别重叠的日期范围,按指定10分钟时间间隔汇总数据
如何识别重叠的日期范围、日期出现次数、确定当前记录和下一条记录之间相差的天数【SQL开发实战技巧】这一系列博主当作复习旧知识来进行写作,毕竟SQL开发在数据分析场景非常重要且基础,面试也会经常问SQL开发和调优经验,相信当我写完这一系列文章,也能再有所收获,未来面对SQL面试也能游刃有余~。例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
【SQL开发实战技巧】系列(二十一):数据仓库中时间类型操作(进阶)识别重叠的日期范围,按指定10分钟时间间隔汇总数据