SQL Server 中master..spt_values的应用

今天在做数据分析报表的时候遇到一个这样的问题。

表结构如下。
部门编码、部门名称、部门人员ID(中间用逗号分割)

我想通过和人员表链接,查询出一个新的数据集,查询出的结果集格式如下:
人员信息(ID或者姓名)、部门编码、部门名称

以前都是通过程序遍历拆分表字段组成新的集合字段,然后在结合SQL语句查询出结果集,但是这个报表要求只能通过SQL语句实现,以前记得可以通过写字段分割函数再结合游标实现。然而今天在网上无意间找到一个新的方法。用“master..spt_values”来实现,具体实现方法见下面实例1感觉这个东西太好用了。把网上的实例都整理了一下,希望各路大神批评指教,也希望大家继续把这方面的应用贴上.

select number from master..spt_values with(nolock) where type=‘P‘
/**解释:master..spt_values表的字段值为P的对应number字段值是从0-2047*/ 

--1.将字符串转换为列显示 

if object_id(‘tb‘) is not null drop table tb
go
create table tb([编号] varchar(3),[产品] varchar(2),[数量] int,[单价] int,[金额] int,[序列号] varchar(8))
insert into tb([编号],[产品],[数量],[单价],[金额],[序列号])
select ‘001‘,‘AA‘,3,5,15,‘12,13,14‘ union all
select ‘002‘,‘BB‘,8,9,13,‘22,23,24‘
go
select [编号],[产品],[数量],[单价],[金额]
,substring([序列号],b.number,charindex(‘,‘,[序列号]+‘,‘,b.number)-b.number) as [序列号]
from tb a with(nolock),master..spt_values b with(nolock)
where b.number>=1 and b.number<len(a.[序列号]) and b.type=‘P‘
and substring(‘,‘+[序列号],number,1)=‘,‘
go
drop table tb
go
/**
编号   产品   数量          单价          金额          序列号
---- ---- ----------- ----------- ----------- --------
001  AA   3           5           15          12
001  AA   3           5           15          13
001  AA   3           5           15          14
002  BB   8           9           13          22
002  BB   8           9           13          23
002  BB   8           9           13          24
*/
---------- 

--2.第四个逗号之前的字符串
declare @str varchar(100)
set @str=‘10,102,10254,103265,541,2154,41,156‘
;with cte as(
select left(@str,number-1) as ss,row_number()over(order by getdate()) as xh
from master..spt_values with(nolock)
where number>=1 and number<=len(@str+‘,‘) and type=‘P‘
and substring(@str+‘,‘,number,1)=‘,‘
)select ss from cte where xh=4
/**
ss
-------------------
10,102,10254,103265
*/
---------- 

--3.找出两句话中相同的汉字
declare @Lctext1 varchar(100)
declare @Lctext2 varchar(100)
set @Lctext1=‘我们都是来自五湖四海的朋友‘
set @Lctext2=‘朋友多了路真的好走吗‘
select substring(@Lctext2,number,1) as value
from master..spt_values with(nolock)
where type=‘P‘ and number>=1 and number<=len(@Lctext2)
and charindex(substring(@Lctext2,number,1),@Lctext1,number)>1
/**
value
-----
朋
友
的
*/
--------- 

--4.提取两个日期之间的所有月份
if object_id(‘tb‘) is not null drop table tb
go
create table tb(id int identity(1,1),startDate varchar(10),endDate varchar(10))
insert into tb(startDate,endDate) select ‘2013-01-01‘,‘2013-09-25‘
go
declare @startDate varchar(10)
declare @endDate varchar(10)
select @startDate=startDate,@endDate=endDate from tb with(nolock)
select convert(varchar(7),dateadd(mm,number,@startDate),120) as [月份]
from master..spt_values with(nolock)
where type=‘P‘ and number>=0
and dateadd(mm,number,@startDate)<=@endDate
go
drop table tb
go
/**
月份
-------
2013-01
2013-02
2013-03
2013-04
2013-05
2013-06
2013-07
2013-08
2013-09
*/
--------- 

--5.求一个日期所在月份的所有日期
declare @date datetime
set @date=‘2013-08-31‘
select convert(char(7),@date,120)+‘-‘+right(‘0‘+convert(varchar(2),number),2) as [日期格式1]
,ltrim(year(@date))+right(100+month(@date),2)+right(‘0‘+ltrim(number),2) as [日期格式2]
from master..spt_values with(nolock)
where type=‘P‘ and number>=1
--and number<=datediff(dd,@date,dateadd(mm,1,@date)) --对于mssql而言该语句不试用于2013-08-31的情况,这时由于9月没有31号,固计算出来的天数是30天
and number<=datediff(dd,convert(char(7),@date,120)+‘-01‘,convert(char(7),dateadd(mm,1,@date),120)+‘-01‘)--转换为1号来计算天数
/**
日期格式1       日期格式2
----------- --------------------
2013-08-01  20130801
2013-08-02  20130802
2013-08-03  20130803
2013-08-04  20130804
2013-08-05  20130805
2013-08-06  20130806
2013-08-07  20130807
2013-08-08  20130808
2013-08-09  20130809
2013-08-10  20130810
2013-08-11  20130811
2013-08-12  20130812
2013-08-13  20130813
2013-08-14  20130814
2013-08-15  20130815
2013-08-16  20130816
2013-08-17  20130817
2013-08-18  20130818
2013-08-19  20130819
2013-08-20  20130820
2013-08-21  20130821
2013-08-22  20130822
2013-08-23  20130823
2013-08-24  20130824
2013-08-25  20130825
2013-08-26  20130826
2013-08-27  20130827
2013-08-28  20130828
2013-08-29  20130829
2013-08-30  20130830
2013-08-31  20130831
*/
--------- 

--6.根据给定时间为基准以2小时为划分,得出一天划分出的时间段
declare @time varchar(5)
set @time=‘11:13‘
select ltrim(a.number)+right(@time,3)+‘-‘+ltrim(b.number)+right(@time,3) as [划分结果]
from master..spt_values a with(nolock),master..spt_values b with(nolock)
where a.type=‘P‘ and b.type=‘P‘
and a.number>=left(@time,2) and b.number<=24
and a.number+2=b.number
/**
划分结果
-----------------------------------
11:13-13:13
12:13-14:13
13:13-15:13
14:13-16:13
15:13-17:13
16:13-18:13
17:13-19:13
18:13-20:13
19:13-21:13
20:13-22:13
21:13-23:13
22:13-24:13
*/
--------- 

--7.将字符串显示为行列
if object_id(‘tb‘) is not null drop table tb
create table tb(id int identity(1,1),s nvarchar(100))
insert into tb(s) select ‘车位地址1,车位状况1|车位地址2,车位状况2|车位地址n,车位状况n‘
;with cte as(
select substring(s,number,charindex(‘|‘,s+‘|‘,number)-number) as ss
from tb with(nolock),master..spt_values with(nolock)
where type=‘P‘ and number>=1 and number<=len(s)
and substring(‘|‘+s,number,1)=‘|‘
)select left(ss,charindex(‘,‘,ss)-1)as s1,substring(ss,charindex(‘,‘,ss)+1,len(ss))as s2 from cte
drop table tb
/**
s1             s2
----------- ------------
车位地址1      车位状况1
车位地址2      车位状况2
车位地址n      车位状况n
*/
时间: 2024-10-17 11:43:51

SQL Server 中master..spt_values的应用的相关文章

SQL Server优化技巧之SQL Server中的&quot;MapReduce&quot;

日常的OLTP环境中,有时会涉及到一些统计方面的SQL语句,这些语句可能消耗巨大,进而影响整体运行环境,这里我为大家介绍如何利用SQL Server中的”类MapReduce”方式,在特定的统计情形中不牺牲响应速度的情形下减少资源消耗. 我们可能经常会利用开窗函数对巨大的数据集进行分组统计排序.比如下面的例子: 脚本环境 /* This script creates two new tables in AdventureWorks: dbo.bigProduct dbo.bigTransacti

在SQL SERVER中实现RSA加解密函数(第二版)

/*************************************************** 作者:herowang(让你望见影子的墙) 日期:2010.1.5 注: 转载请保留此信息 更多内容,请访问我的博客:blog.csdn.NET/herowang ****************************************************/ /* 本次修改增加了unicode的支持,但是加密后依然显示为进制数据,因为进行RSA加密后所得到的unicode编码是无

SQL Server 中WITH (NOLOCK)浅析

原文:SQL Server 中WITH (NOLOCK)浅析 概念介绍 开发人员喜欢在SQL脚本中使用WITH(NOLOCK), WITH(NOLOCK)其实是表提示(table_hint)中的一种.它等同于 READUNCOMMITTED . 具体的功能作用如下所示(摘自MSDN): 1: 指定允许脏读.不发布共享锁来阻止其他事务修改当前事务读取的数据,其他事务设置的排他锁不会阻碍当前事务读取锁定数据.允许脏读可能产生较多的并发操作,但其代价是读取以后会被其他事务回滚的数据修改.这可能会使您的

[转]细说SQL Server中的加密

简介 加密是指通过使用密钥或密码对数据进行模糊处理的过程.在SQL Server中,加密并不能替代其他的安全设置,比如防止未被授权的人访问数据库或是数据库实例所在的Windows系统,甚至是数据库所在的机房,而是作为当数据库被破解或是备份被窃取后的最后一道防线.通过加密,使得未被授权的人在没有密钥或密码的情况下所窃取的数据变得毫无意义.这种做法不仅仅是为了你的数据安全,有时甚至是法律所要求的(像国内某知名IT网站泄漏密码这种事在中国可以道歉后不负任何责任了事,在米国妥妥的要破产清算). SQL

SQL Server中关于跟踪(Trace)那点事

前言 一提到跟踪俩字,很多人想到警匪片中的场景,同样在我们的SQL Server数据库中“跟踪”也是无处不在的,如果我们利用好了跟踪技巧,就可以针对某些特定的场景做定向分析,找出充足的证据来破案. 简单的举几个应用场景: 在线生产库为何突然宕机?数百张数据表为何不翼而飞?刚打好补丁的系统为何屡遭黑手?新添加的信息表为何频频丢失?某张表字段的突然更改,究竟为何人所为?这些个匿名的访问背后,究竟是人是鬼?突然增加的增量数据,究竟是对是错?数百兆的日志爆炸式的增长背后又隐藏着什么?这一且的背后,是应用

SQL Server中存储过程 比 直接运行SQL语句慢的原因

问题是存储过程的Parameter sniffing 在很多的资料中都描述说SQLSERVER的存储过程较普通的SQL语句有以下优点: 1. 存储过程只在创造时进行编译即可,以后每次执行存储过程都不需再重新编译,而我们通常使用的SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度. 2. 经常会遇到复杂的业务逻辑和对数据库的操作,这个时候就会用SP来封装数据库操作.当对数据库进行复杂操作时(如对多个表进行 Update,Insert,Query,Delete时),可将此复杂操作用

SQL Server 2008 master 数据库损坏解决总结

SQL Server 2008 master数据库损坏后,SQL SERVER服务启动失败,查看错误日志,你会看到下面错误信息: 2015-10-27 10:15:21.01 spid6s      Starting up database 'master'.   2015-10-27 10:15:23.01 spid6s      错误: 9003,严重性: 20,状态: 1.   2015-10-27 10:15:23.01 spid6s      The log scan number (

SQL Server中存储过程比直接运行SQL语句慢的原因

原文:SQL Server中存储过程比直接运行SQL语句慢的原因 在很多的资料中都描述说SQLSERVER的存储过程较普通的SQL语句有以下优点: 1.       存储过程只在创造时进行编译即可,以后每次执行存储过程都不需再重新编译,而我们通常使用的SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度. 2.       经常会遇到复杂的业务逻辑和对数据库的操作,这个时候就会用SP来封装数据库操作.当对数据库进行复杂操作时(如对多个表进行 Update,Insert,Query

????SQL Server中默认数据库和默认表的作用

我们知道Oracle数据库的安装架构可以是1个数据库对应1个或多个实例.而在SQL Server中,其架构和Oracle 完全相反,它是1个实例(默认实例名为Hostname主机名)下面包含多个数据库,在sqlserver数据库中(2000,2005,2008等),主要包含4个默认的数据库,分别是master数据库.model数据库.tempdb数据库和msdb数据库.这些数据库是SQL Server的心脏和灵魂.另外,还默认安装了两个实例数据库,分别是:northwind数据库和pubs数据库