標籤:master..spt_values
今天在做資料分析報表的時候遇到一個這樣的問題。
表結構如下。
部門編碼、部門名稱、部門人員ID(中間用逗號分割)
650) this.width=650;" title="1.jpg" src="http://s3.51cto.com/wyfs02/M00/49/B0/wKiom1QZL0fyofCQAAJXUFPFIdk500.jpg" alt="wKiom1QZL0fyofCQAAJXUFPFIdk500.jpg" />
我想通過和人員錶鏈接,查詢出一個新的資料集,查詢出的結果集格式如下:
人員資訊(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)<[email protected]
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
*/
本文出自 “靈雨飄零部落格” 部落格,請務必保留此出處http://101779.blog.51cto.com/91779/1554325
SQL Server 中master..spt_values的應用