求高手写个函数,重分!重分!重分!

Airch 2011-10-11 10:16:11
假如有表如下:

userid name

1 李三|张四


谁帮忙写个split函数能到这个效果

userid name

1 李三

2 张四


大大们帮帮忙!!!
...全文
92 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
Airch 2011-10-12
  • 打赏
  • 举报
回复
搞定了 写了个函数返回表,利用子查询解决

Alter FUNCTION [dbo].[Split]
(
@str varchar ( max ) ,
@split varchar ( 10 )
)
RETURNS @t TABLE
(
v varchar(max)
)
AS
BEGIN
DECLARE @XmlIDs XML
SET @xmlIDs = '<IDs> <ID>' + REPLACE(@str, @split , '</ID><ID>') + '</ID>' + '</IDs>'
INSERT INTO @t SELECT x.v.value('.','varchar(max)')
FROM @xmlIDs.nodes('/IDs/ID') x(v)
RETURN END

SELECT Name FROM Pub_User_tb WHERE '爱哈哈' in( select * from Split(Name,'|'))
q465897859 2011-10-12
  • 打赏
  • 举报
回复
select row_number() over(order by getdate()) userid,name=substring(a.name,b.number,charindex('|',a.name+'|',b.number)-b.number) 
from tb a,master..spt_values b where b.type='p' and b.number<=len(a.name) and charindex('|','|'+a.name,b.number)=b.number
Airch 2011-10-12
  • 打赏
  • 举报
回复
刚自己写了个 只能返回表 也就跟你们写的cte一样的
前面我说的语法冲突。。。
-晴天 2011-10-12
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 airch 的回复:]
你们的方法都可以,关键是数据是在表里,里面的我要查询出主键id和name,而name也不是固定的就一个竖线
最好是用函数,我要跟其他的sql查询一起用
[/Quote]

你给一条记录中的两个字段,让函数将它们分成多个记录,其中的ID还是主键,这能成么?
Airch 2011-10-12
  • 打赏
  • 举报
回复
你们的方法都可以,关键是数据是在表里,里面的我要查询出主键id和name,而name也不是固定的就一个竖线
最好是用函数,我要跟其他的sql查询一起用
薇薇 2011-10-11
  • 打赏
  • 举报
回复
--合并分拆表
/******************************************************************************************************************************************************
合并分拆表数据

整理人:中国风(Roy)

日期:2008.06.06
******************************************************************************************************************************************************/

--> --> (Roy)生成測試數據

if not object_id('Tab') is null
drop table Tab
Go
Create table Tab([Col1] int,[Col2] nvarchar(1))
Insert Tab
select 1,N'a' union all
select 1,N'b' union all
select 1,N'c' union all
select 2,N'd' union all
select 2,N'e' union all
select 3,N'f'
Go

合并表:

SQL2000用函数:

go
if object_id('F_Str') is not null
drop function F_Str
go
create function F_Str(@Col1 int)
returns nvarchar(100)
as
begin
declare @S nvarchar(100)
select @S=isnull(@S+',','')+Col2 from Tab where Col1=@Col1
return @S
end
go
Select distinct Col1,Col2=dbo.F_Str(Col1) from Tab

go

SQL2005用XML:

方法1:

select
a.Col1,Col2=stuff(b.Col2.value('/R[1]','nvarchar(max)'),1,1,'')
from
(select distinct COl1 from Tab) a
Cross apply
(select COl2=(select N','+Col2 from Tab where Col1=a.COl1 For XML PATH(''), ROOT('R'), TYPE))b

方法2:

select
a.Col1,COl2=replace(b.Col2.value('/Tab[1]','nvarchar(max)'),char(44)+char(32),char(44))
from
(select distinct COl1 from Tab) a
cross apply
(select Col2=(select COl2 from Tab where COl1=a.COl1 FOR XML AUTO, TYPE)
.query('<Tab>
{for $i in /Tab[position()<last()]/@COl2 return concat(string($i),",")}
{concat("",string(/Tab[last()]/@COl2))}
</Tab>')
)b

SQL05用CTE:

;with roy as(select Col1,Col2,row=row_number()over(partition by COl1 order by COl1) from Tab)
,Roy2 as
(select COl1,cast(COl2 as nvarchar(100))COl2,row from Roy where row=1
union all
select a.Col1,cast(b.COl2+','+a.COl2 as nvarchar(100)),a.row from Roy a join Roy2 b on a.COl1=b.COl1 and a.row=b.row+1)
select Col1,Col2 from Roy2 a where row=(select max(row) from roy where Col1=a.COl1) order by Col1 option (MAXRECURSION 0)


生成结果:
/*
Col1 COl2
----------- ------------
1 a,b,c
2 d,e
3 f

(3 行受影响)
*/


拆分表:

--> --> (Roy)生成測試數據

if not object_id('Tab') is null
drop table Tab
Go
Create table Tab([Col1] int,[COl2] nvarchar(5))
Insert Tab
select 1,N'a,b,c' union all
select 2,N'd,e' union all
select 3,N'f'
Go

SQL2000用辅助表:
if object_id('Tempdb..#Num') is not null
drop table #Num
go
select top 100 ID=Identity(int,1,1) into #Num from syscolumns a,syscolumns b
Select
a.Col1,COl2=substring(a.Col2,b.ID,charindex(',',a.Col2+',',b.ID)-b.ID)
from
Tab a,#Num b
where
charindex(',',','+a.Col2,b.ID)=b.ID --也可用 substring(','+a.COl2,b.ID,1)=','


SQL2005用Xml:

select
a.COl1,b.Col2
from
(select Col1,COl2=convert(xml,'<root><v>'+replace(COl2,',','</v><v>')+'</v></root>') from Tab)a
outer apply
(select Col2=C.v.value('.','nvarchar(100)') from a.COl2.nodes('/root/v')C(v))b




SQL05用CTE:

;with roy as
(select Col1,COl2=cast(left(Col2,charindex(',',Col2+',')-1) as nvarchar(100)),Split=cast(stuff(COl2+',',1,charindex(',',Col2+','),'') as nvarchar(100)) from Tab
union all
select Col1,COl2=cast(left(Split,charindex(',',Split)-1) as nvarchar(100)),Split= cast(stuff(Split,1,charindex(',',Split),'') as nvarchar(100)) from Roy where split>''
)
select COl1,COl2 from roy order by COl1 option (MAXRECURSION 0)

生成结果:
/*
Col1 COl2
----------- -----
1 a
1 b
1 c
2 d
2 e
3 f
*/
--小F-- 2011-10-11
  • 打赏
  • 举报
回复
--参考
拆分表:

--> --> (Roy)生成測試數據

if not object_id('Tab') is null
drop table Tab
Go
Create table Tab([Col1] int,[COl2] nvarchar(5))
Insert Tab
select 1,N'a,b,c' union all
select 2,N'd,e' union all
select 3,N'f'
Go

--SQL2000用辅助表:
if object_id('Tempdb..#Num') is not null
drop table #Num
go
select top 100 ID=Identity(int,1,1) into #Num from syscolumns a,syscolumns b
Select
a.Col1,COl2=substring(a.Col2,b.ID,charindex(',',a.Col2+',',b.ID)-b.ID)
from
Tab a,#Num b
where
charindex(',',','+a.Col2,b.ID)=b.ID --也可用 substring(','+a.COl2,b.ID,1)=','
--2000不使用辅助表
Select
a.Col1,COl2=substring(a.Col2,b.number,charindex(',',a.Col2+',',b.number)-b.number)
from
Tab a join master..spt_values b
ON B.type='p' AND B.number BETWEEN 1 AND LEN(A.col2)
where
substring(','+a.COl2,b.number,1)=','


SQL2005用Xml:

select
a.COl1,b.Col2
from
(select Col1,COl2=convert(xml,'<root><v>'+replace(COl2,',','</v><v>')+'</v></root>') from Tab)a
outer apply
(select Col2=C.v.value('.','nvarchar(100)') from a.COl2.nodes('/root/v')C(v))b




SQL05用CTE:

;with roy as
(select Col1,COl2=cast(left(Col2,charindex(',',Col2+',')-1) as nvarchar(100)),Split=cast(stuff(COl2+',',1,charindex(',',Col2+','),'') as nvarchar(100)) from Tab
union all
select Col1,COl2=cast(left(Split,charindex(',',Split)-1) as nvarchar(100)),Split= cast(stuff(Split,1,charindex(',',Split),'') as nvarchar(100)) from Roy where split>''
)
select COl1,COl2 from roy order by COl1 option (MAXRECURSION 0)

生成结果:
/*
Col1 COl2
----------- -----
1 a
1 b
1 c
2 d
2 e
3 f
*/
中国风 2011-10-11
  • 打赏
  • 举报
回复
--> --> (Roy)生成測試數據

if not object_id('Tempdb..#T') is null
drop table #T
Go
Create table #T([userid] int,[name] nvarchar(5))
Insert #T
select 1,N'李三|张四'
Go

Select
a.[userid],[name]=substring(a.[name],b.number,charindex('|',a.[name]+'|',b.number)-b.number)
from
#T a,master.dbo.spt_values b
where
charindex('|','|'+a.[name],b.number)=b.number and b.type='P'

/*
userid name
1 李三
1 张四*/
-晴天 2011-10-11
  • 打赏
  • 举报
回复
用不着写函数,直接查询就行了:
create table tb(userid int,name nvarchar(20))
insert into tb select 1,'李三|张四'
go
select userid,LEFT(name,charindex('|',name)-1) as name from tb
union all
select userid+1,RIGHT(name,len(name)-charindex('|',name)) from tb
/*
userid name
----------- --------------------
1 李三
2 张四

(2 行受影响)

*/
go
drop table tb


中国风 2011-10-11
  • 打赏
  • 举报
回复
--> --> (Roy)生成測試數據

if not object_id('Tempdb..#T') is null
drop table #T
Go
Create table #T([userid] int,[name] nvarchar(5))
Insert #T
select 1,N'李三|张四'
Go

;with roy as
(select [userid],[name]=cast(left([name],charindex('|',[name]+'|')-1) as nvarchar(100)),Split=cast(stuff([name]+'|',1,charindex('|',[name]+'|'),'') as nvarchar(100)) from #T
union all
select [userid],[name]=cast(left(Split,charindex('|',Split)-1) as nvarchar(100)),Split= cast(stuff(Split,1,charindex('|',Split),'') as nvarchar(100)) from Roy where split>''
)
select [userid],[name] from roy order by [userid] option (MAXRECURSION 0)
/*

userid name
1 李三
1 张四*/
Airch 2011-10-11
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 roy_88 的回复:]
参照方法
http://topic.csdn.net/u/20080612/22/c850499f-bce3-4877-82d5-af2357857872.html
[/Quote]

好晚了 明天瞅瞅
Airch 2011-10-11
  • 打赏
  • 举报
回复
只能给100分 谁帮忙弄出来 我再加

22,209

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧