34,591
社区成员
发帖
与我相关
我的任务
分享
if OBJECT_ID('test') is not null
drop table test
Go
create table test
(
[weight] varchar(100),
unit varchar(10)
)
Go
insert into test
select '15.5','g'
union all
select '18.6','g'
union all
select '12.5/16','g'
union all
select '10/18/24','g'
GO
select * from nums ---数字辅助表,详见http://blog.csdn.net/yubofighting/article/details/6826669
select case when CHARINDEX('/',[weight])>0 then SUBSTRING([weight]+'/',n,charindex('/',[weight]+'/',n)-n) else [weight] end from
(
select test.*,n from test,nums where SUBSTRING('/'+[weight],n,1)='/' ---找到'/'所在的位置
)t
create table tb(重量 varchar(50),单位 varchar(10))
insert into tb values('15.5' ,'g')
insert into tb values('18.6' ,'g')
insert into tb values('12.5/16' ,'g')
insert into tb values('10/18/24' ,'g')
go
select 重量 重量1, 0 重量2 , 0 重量3 ,单位 from tb where len(重量) - len(replace(重量,'/','')) = 0
union all
select replace(parsename(replace(replace(重量,'.','#'),'/','.'),2),'#','.') 重量1,
replace(parsename(replace(replace(重量,'.','#'),'/','.'),1),'#','.') 重量2 ,
0 重量3 ,单位
from tb where len(重量) - len(replace(重量,'/','')) = 1
union all
select replace(parsename(replace(replace(重量,'.','#'),'/','.'),3),'#','.') 重量1,
replace(parsename(replace(replace(重量,'.','#'),'/','.'),2),'#','.') 重量2 ,
replace(parsename(replace(replace(重量,'.','#'),'/','.'),1),'#','.') 重量3 ,单位
from tb where len(重量) - len(replace(重量,'/','')) = 2
drop table tb
/*
重量1 重量2 重量3 单位
----- ----- ----- ----
15.5 0 0 g
18.6 0 0 g
12.5 16 0 g
10 18 24 g
(所影响的行数为 4 行)
*/
PARSENAME
返回对象名的指定部分。可以检索的对象部分有对象名、所有者名称、数据库名称和服务器名称。
说明 PARSENAME 函数不表明所指定名称的对象是否存在,而只是返回给定对象名的指定部分。
语法
PARSENAME ( 'object_name' , object_piece )
参数
'object_name'
要检索其指定部分的对象名。object_name 是 sysname 值。本参数是可选的合法对象名。如果该对象名的所有部分均符合要求,则该名称由以下四部分组成:服务器名称、数据库名称、所有者名称和对象名。
object_piece
要返回的对象部分。object_piece 是 int 值,可以为下列值。
Value 描述
1 对象名
2 所有者名称
3 数据库名称
4 服务器名称
返回类型
nchar
注释
如果符合下列条件之一,则 PARSENAME 返回 NULL 值:
object_name 或 object_piece 为 NULL 值。
发生语法错误。
所请求的对象部分长度为 0,并且是无效的 Microsoft® SQL Server™ 标识符。零长度的对象名将导致整个合法名称无效。
示例
本示例使用 PARSENAME 返回有关 pubs 数据库中 authors 表的信息。
USE pubs
SELECT PARSENAME('pubs..authors', 1) AS 'Object Name'
SELECT PARSENAME('pubs..authors', 2) AS 'Owner Name'
SELECT PARSENAME('pubs..authors', 3) AS 'Database Name'
SELECT PARSENAME('pubs..authors', 4) AS 'Server Name'
下面是结果集:
Object Name
------------------------------
authors
(1 row(s) affected)
Owner Name
------------------------------
(null)
(1 row(s) affected)
Database Name
------------------------------
pubs
(1 row(s) affected)
Server Name
------------------------------
(null)
(1 row(s) affected)
select 重量 重量1, 0 重量2 , 0 重量3 ,0 重量4, 单位 from tb where len(重量) - len(replace(重量,'/','')) = 0
union all
select replace(parsename(replace(replace(重量,'.','#'),'/','.'),2),'#','.') 重量1,
replace(parsename(replace(replace(重量,'.','#'),'/','.'),1),'#','.') 重量2 ,
0 重量3 ,0 重量4, 单位
from tb where len(重量) - len(replace(重量,'/','')) = 1
union all
select replace(parsename(replace(replace(重量,'.','#'),'/','.'),3),'#','.') 重量1,
replace(parsename(replace(replace(重量,'.','#'),'/','.'),2),'#','.') 重量2 ,
replace(parsename(replace(replace(重量,'.','#'),'/','.'),1),'#','.') 重量3 ,0 重量4 , 单位
from tb where len(重量) - len(replace(重量,'/','')) = 2
union all
select replace(parsename(replace(replace(重量,'.','#'),'/','.'),4),'#','.') 重量1,
replace(parsename(replace(replace(重量,'.','#'),'/','.'),3),'#','.') 重量2 ,
replace(parsename(replace(replace(重量,'.','#'),'/','.'),2),'#','.') 重量3 ,
replace(parsename(replace(replace(重量,'.','#'),'/','.'),1),'#','.') 重量4 , 单位
from tb where len(重量) - len(replace(重量,'/','')) = 3
/*
标题:简单数据拆分(version 2.0)
作者:爱新觉罗.毓华(十八年风雨,守得冰山雪莲花开)
时间:2010-05-07
地点:重庆航天职业学院
描述:
有表tb, 如下:
id value
----------- -----------
1 aa,bb
2 aaa,bbb,ccc
欲按id,分拆value列, 分拆后结果如下:
id value
----------- --------
1 aa
1 bb
2 aaa
2 bbb
2 ccc
*/
--1. 旧的解决方法(sql server 2000)
create table tb(id int,value varchar(30))
insert into tb values(1,'aa,bb')
insert into tb values(2,'aaa,bbb,ccc')
go
--方法1.使用临时表完成
SELECT TOP 8000 id = IDENTITY(int, 1, 1) INTO # FROM syscolumns a, syscolumns b
SELECT A.id, value = SUBSTRING(A.[value], B.id, CHARINDEX(',', A.[value] + ',', B.id) - B.id)
FROM tb A, # B
WHERE SUBSTRING(',' + A.[value], B.id, 1) = ','
DROP TABLE #
--方法2.如果数据量小,可不使用临时表
select a.id , value = substring(a.value , b.number , charindex(',' , a.value + ',' , b.number) - b.number)
from tb a join master..spt_values b
on b.type='p' and b.number between 1 and len(a.value)
where substring(',' + a.value , b.number , 1) = ','
--2. 新的解决方法(sql server 2005)
create table tb(id int,value varchar(30))
insert into tb values(1,'aa,bb')
insert into tb values(2,'aaa,bbb,ccc')
go
--方法1.使用xml完成
SELECT A.id, B.value FROM
(
SELECT id, [value] = CONVERT(xml,'<root><v>' + REPLACE([value], ',', '</v><v>') + '</v></root>') FROM tb
) A OUTER APPLY
(
SELECT value = N.v.value('.', 'varchar(100)') FROM A.[value].nodes('/root/v') N(v)
) B
--方法2.使用CTE完成
;with tt as
(select id,[value]=cast(left([value],charindex(',',[value]+',')-1) as nvarchar(100)),Split=cast(stuff([value]+',',1,charindex(',',[value]+','),'') as nvarchar(100)) from tb
union all
select id,[value]=cast(left(Split,charindex(',',Split)-1) as nvarchar(100)),Split= cast(stuff(Split,1,charindex(',',Split),'') as nvarchar(100)) from tt where split>''
)
select id,[value] from tt order by id option (MAXRECURSION 0)
DROP TABLE tb
/*
id value
----------- ------------------------------
1 aa
1 bb
2 aaa
2 bbb
2 ccc
(5 行受影响)
*/