大神帮忙看一下,sql 将一个字段分成多个字段,以第二个“-”符号分隔,

wanglanxuan1 2015-08-27 08:49:47
falarm
1 -a-b
2 -a-b-c
3 -a
4 -c-b



要得到的结果
falarm
1 -a
2 -b
3 -a
4 -b
5 -c
6 -a
7 -c
8 -b
...全文
289 点赞 收藏 18
写回复
18 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
zbdzjx 2015-09-06
引用 17 楼 wanglanxuan1 的回复:
[quote=引用 3 楼 zbdzjx 的回复:]
with table1(falarm) as
(
  SELECT '-a-b' UNION ALL
  SELECT '-a-b-c' UNION ALL
  SELECT '-a' UNION ALL
  SELECT '-c-b' 
)
select '-' + falarm falarm from 
(
  SELECT B.falarm FROM 
  (
    SELECT [value] = CONVERT(XML , '<v>' + REPLACE(falarm , '-' , '</v><v>') + '</v>') from table1
  ) A
  OUTER APPLY 
  (
    SELECT falarm = N.v.value('.' , 'varchar(100)') FROM A.[value].nodes('/v') N ( v )
  ) B
) c where falarm <>''
你好 能不能解释一下这句代码的意思 谢谢了 OUTER APPLY ( SELECT falarm = N.v.value('.' , 'varchar(100)') FROM A.[value].nodes('/v') N ( v ) ) B [/quote] 哈哈,我也不明白,我是在网上搜的语句,再改一改的。 可以看一下: http://www.jb51.net/article/23665.htm http://blog.csdn.net/beirut/article/details/8209145
回复
wanglanxuan1 2015-09-06
引用 3 楼 zbdzjx 的回复:
with table1(falarm) as
(
  SELECT '-a-b' UNION ALL
  SELECT '-a-b-c' UNION ALL
  SELECT '-a' UNION ALL
  SELECT '-c-b' 
)
select '-' + falarm falarm from 
(
  SELECT B.falarm FROM 
  (
    SELECT [value] = CONVERT(XML , '<v>' + REPLACE(falarm , '-' , '</v><v>') + '</v>') from table1
  ) A
  OUTER APPLY 
  (
    SELECT falarm = N.v.value('.' , 'varchar(100)') FROM A.[value].nodes('/v') N ( v )
  ) B
) c where falarm <>''
你好 能不能解释一下这句代码的意思 谢谢了 OUTER APPLY ( SELECT falarm = N.v.value('.' , 'varchar(100)') FROM A.[value].nodes('/v') N ( v ) ) B
回复
qq_17482963 2015-08-31
引用 13 楼 wanglanxuan1 的回复:
[quote=引用 10 楼 qq_17482963 的回复:] 或者會有更簡單的方法
高手啊,再帮忙看一个吧: 现有表A falarm 个数 -ab 7 -ac 5 -bc 4 -dc 3 -be 1 把表A中个数的前四名放到表B 得到的结果为(姓名 电话可以从另一张表C中得到): 姓名 电话 第一 第二 第三 第四 总数 ... ..... 7 5 4 3 19 我是刚接触sql 谢谢了[/quote]
insert into B(第一,第二,第三,第四,總數)
select 
sum(case when id=1 then 個數 end)'第一',
sum(case when id=2 then 個數 end)'第二',
sum(case when id=3 then 個數 end)'第三',
max(case when id=4 then 個數 end)'第四',
sum(個數) '總數' from(
select top 4 ROW_NUMBER() over(order by id desc)id,* from A) a
回复
wanglanxuan1 2015-08-31
引用 11 楼 zbdzjx 的回复:
[quote=引用 6 楼 wanglanxuan1 的回复:] [quote=引用 3 楼 zbdzjx 的回复:]
with table1(falarm) as
(
  SELECT '-a-b' UNION ALL
  SELECT '-a-b-c' UNION ALL
  SELECT '-a' UNION ALL
  SELECT '-c-b' 
)
select '-' + falarm falarm from 
(
  SELECT B.falarm FROM 
  (
    SELECT [value] = CONVERT(XML , '<v>' + REPLACE(falarm , '-' , '</v><v>') + '</v>') from table1
  ) A
  OUTER APPLY 
  (
    SELECT falarm = N.v.value('.' , 'varchar(100)') FROM A.[value].nodes('/v') N ( v )
  ) B
) c where falarm <>''
谢谢!不过这只是我举得一个例子,我想要的结果是不是单有这几行,有很多行的情况下如何做?如: falarm 1 -abc-ef-cda 2 -gh-ty-ccc 3 -sc-ch 4 -cd-dd 5 -....... . ........ . ........ . ........ . ........ ...[/quote] 一样啊!就是改一下with里面的union all相关的语句。
with table1(falarm) as
(
  SELECT '-abc-ef-cda' UNION ALL
  SELECT '-gh-ty-ccc' UNION ALL
  SELECT '-sc-ch' UNION ALL
  SELECT '-cd-dd' 
)
select '-' + falarm falarm from 
(
  SELECT B.falarm FROM 
  (
    SELECT [value] = CONVERT(XML , '<v>' + REPLACE(falarm , '-' , '</v><v>') + '</v>') from table1
  ) A
  OUTER APPLY 
  (
    SELECT falarm = N.v.value('.' , 'varchar(100)') FROM A.[value].nodes('/v') N ( v )
  ) B
) c where falarm <>''
如果你的记录存在一个表中,例如表名叫tb1,表中的那列名falarm,那语句就是如下:
select '-' + falarm falarm from 
(
  SELECT B.falarm FROM 
  (
    SELECT [value] = CONVERT(XML , '<v>' + REPLACE(falarm , '-' , '</v><v>') + '</v>') from tb1
  ) A
  OUTER APPLY 
  (
    SELECT falarm = N.v.value('.' , 'varchar(100)') FROM A.[value].nodes('/v') N ( v )
  ) B
) c where falarm <>''
[/quote] 高手啊,再帮忙看一个吧: 现有表A falarm 个数 -ab 7 -ac 5 -bc 4 -dc 3 -be 1 把表A中个数的前四名放到表B 得到的结果为(姓名 电话可以从另一张表C中得到): 姓名 电话 第一 第二 第三 第四 总数 ... ..... 7 5 4 3 19 我是刚接触sql 谢谢了
回复
wanglanxuan1 2015-08-31
引用 10 楼 qq_17482963 的回复:
或者會有更簡單的方法
高手啊,再帮忙看一个吧: 现有表A falarm 个数 -ab 7 -ac 5 -bc 4 -dc 3 -be 1 把表A中个数的前四名放到表B 得到的结果为(姓名 电话可以从另一张表C中得到): 姓名 电话 第一 第二 第三 第四 总数 ... ..... 7 5 4 3 19 我是刚接触sql 谢谢了
回复
wanglanxuan1 2015-08-31
引用 15 楼 qq_17482963 的回复:
[quote=引用 13 楼 wanglanxuan1 的回复:] [quote=引用 10 楼 qq_17482963 的回复:] 或者會有更簡單的方法
高手啊,再帮忙看一个吧: 现有表A falarm 个数 -ab 7 -ac 5 -bc 4 -dc 3 -be 1 把表A中个数的前四名放到表B 得到的结果为(姓名 电话可以从另一张表C中得到): 姓名 电话 第一 第二 第三 第四 总数 ... ..... 7 5 4 3 19 我是刚接触sql 谢谢了[/quote]
insert into B(第一,第二,第三,第四,總數)
select 
sum(case when id=1 then 個數 end)'第一',
sum(case when id=2 then 個數 end)'第二',
sum(case when id=3 then 個數 end)'第三',
max(case when id=4 then 個數 end)'第四',
sum(個數) '總數' from(
select top 4 ROW_NUMBER() over(order by id desc)id,* from A) a
[/quote] 最后再问一下 如果想得到的结果再改一下呢: 姓名 电话 第一 第二 第三 第四 总数 ... ..... -ab -ac -bc -dc 19
回复
xxfvba 2015-08-27
;with T(falarm) as (SELECT '-a-b' UNION ALL SELECT '-a-b-c' UNION ALL SELECT '-a' UNION ALL SELECT '-c-b') select '-'+substring(falarm,number,charindex('-',falarm+'-',number)-number) from T,master..spt_values where type='P' and number>=2 and number<=len(falarm) and substring('-'+falarm,number,1)='-'
回复
zbdzjx 2015-08-27
with table1(falarm) as
(
  SELECT '-a-b' UNION ALL
  SELECT '-a-b-c' UNION ALL
  SELECT '-a' UNION ALL
  SELECT '-c-b' 
)
select '-' + falarm falarm from 
(
  SELECT B.falarm FROM 
  (
    SELECT [value] = CONVERT(XML , '<v>' + REPLACE(falarm , '-' , '</v><v>') + '</v>') from table1
  ) A
  OUTER APPLY 
  (
    SELECT falarm = N.v.value('.' , 'varchar(100)') FROM A.[value].nodes('/v') N ( v )
  ) B
) c where falarm <>''
回复
Pact_Alice 2015-08-27
CREATE TABLE #T( falarm varchar(40) ) CREATE TABLE #Fala( falarm varchar(40) ) INSERT INTO #t SELECT '-a-b' UNION ALL SELECT '-a-b-c' UNION ALL SELECT '-a' UNION ALL SELECT '-c-b' DECLARE @i INT ,@MaxLen INT SET @maxLen=(SELECT max(LEN(falarm))FROM #t) SET @i=1 WHILE @i<@maxLen BEGIN INSERT INTO #Fala select * from (SELECT SUBSTRING(falarm,@i,2)AS fala FROM #T )a WHERE a.fala!='' SET @i=@i+2 END SELECT * FROM #Fala
回复
hgwyl 2015-08-27
交给前台split一下不行么
回复
wanglanxuan1 2015-08-27
回复
zbdzjx 2015-08-27
引用 6 楼 wanglanxuan1 的回复:
[quote=引用 3 楼 zbdzjx 的回复:]
with table1(falarm) as
(
  SELECT '-a-b' UNION ALL
  SELECT '-a-b-c' UNION ALL
  SELECT '-a' UNION ALL
  SELECT '-c-b' 
)
select '-' + falarm falarm from 
(
  SELECT B.falarm FROM 
  (
    SELECT [value] = CONVERT(XML , '<v>' + REPLACE(falarm , '-' , '</v><v>') + '</v>') from table1
  ) A
  OUTER APPLY 
  (
    SELECT falarm = N.v.value('.' , 'varchar(100)') FROM A.[value].nodes('/v') N ( v )
  ) B
) c where falarm <>''
谢谢!不过这只是我举得一个例子,我想要的结果是不是单有这几行,有很多行的情况下如何做?如: falarm 1 -abc-ef-cda 2 -gh-ty-ccc 3 -sc-ch 4 -cd-dd 5 -....... . ........ . ........ . ........ . ........ ...[/quote] 一样啊!就是改一下with里面的union all相关的语句。
with table1(falarm) as
(
  SELECT '-abc-ef-cda' UNION ALL
  SELECT '-gh-ty-ccc' UNION ALL
  SELECT '-sc-ch' UNION ALL
  SELECT '-cd-dd' 
)
select '-' + falarm falarm from 
(
  SELECT B.falarm FROM 
  (
    SELECT [value] = CONVERT(XML , '<v>' + REPLACE(falarm , '-' , '</v><v>') + '</v>') from table1
  ) A
  OUTER APPLY 
  (
    SELECT falarm = N.v.value('.' , 'varchar(100)') FROM A.[value].nodes('/v') N ( v )
  ) B
) c where falarm <>''
如果你的记录存在一个表中,例如表名叫tb1,表中的那列名falarm,那语句就是如下:
select '-' + falarm falarm from 
(
  SELECT B.falarm FROM 
  (
    SELECT [value] = CONVERT(XML , '<v>' + REPLACE(falarm , '-' , '</v><v>') + '</v>') from tb1
  ) A
  OUTER APPLY 
  (
    SELECT falarm = N.v.value('.' , 'varchar(100)') FROM A.[value].nodes('/v') N ( v )
  ) B
) c where falarm <>''
回复
qq_17482963 2015-08-27
或者會有更簡單的方法
回复
qq_17482963 2015-08-27
稍微改了一下2樓的方法
CREATE TABLE #T(
falarm varchar(40)
)
CREATE TABLE #Fala(
falarm varchar(40)
)

INSERT INTO #t
SELECT '-ab-bbc' UNION ALL
SELECT '-ab-bc-ce' UNION ALL
SELECT '-ac' UNION ALL
SELECT '-cdd-ba' union all
select '-a-b-c-d' union all
select '-dee-gg-acd-bb' union all
select '-arr-bc-caa-de' union all
select '-at-bpp-cn-dd' union all
select '-agg-bbb-ca-db'

select IDENTITY(int,1,1)id,* into #t2 from #t

DECLARE @i INT ,@MaxLen INT, @pos int,@count int, @sql nvarchar(max), @len int, @tlen int
set @count=(select COUNT(*) from #T)
set @sql=''
while @count>0
begin
SET @i=1
set @MaxLen=(select LEN(falarm) from #t2 where id=@count)
set @pos=1
WHILE @i<@maxLen
BEGIN
set @tlen=@pos
set @pos=(select CHARINDEX('-',falarm,@pos+1) from #t2 where id=@count)
if @pos=0
	set @pos=@MaxLen+1
set @len=@pos-@tlen
set @sql=@sql+'
INSERT INTO #Fala
select * from (SELECT SUBSTRING(falarm,'+convert(nvarchar(10),@tlen)+','+convert(nvarchar(10),@len)+')AS fala FROM #T2 where id='+convert(nvarchar(10),@count)+')a WHERE a.fala!=''''
'
SET @i=@i+@len
END
print 'count='+convert(nvarchar(10),@count)
set @count=@count-1
end
set @sql=@sql+'select * from #Fala'
print @sql
exec(@sql)

drop table #t2
回复
gw6328 2015-08-27
上面写的肯定也适合于多行啊。- -!
回复
wanglanxuan1 2015-08-27
引用 4 楼 xxfvba 的回复:
;with T(falarm) as (SELECT '-a-b' UNION ALL SELECT '-a-b-c' UNION ALL SELECT '-a' UNION ALL SELECT '-c-b') select '-'+substring(falarm,number,charindex('-',falarm+'-',number)-number) from T,master..spt_values where type='P' and number>=2 and number<=len(falarm) and substring('-'+falarm,number,1)='-'
谢谢!不过这只是我举得一个例子,我想要的结果是不是单有这几行,有很多行的情况下如何做?如: falarm 1 -abc-ef-cda 2 -gh-ty-ccc 3 -sc-ch 4 -cd-dd 5 -....... . ........ . ........ . ........ . ........ ...
回复
wanglanxuan1 2015-08-27
引用 2 楼 Landa_Alice 的回复:
CREATE TABLE #T( falarm varchar(40) ) CREATE TABLE #Fala( falarm varchar(40) ) INSERT INTO #t SELECT '-a-b' UNION ALL SELECT '-a-b-c' UNION ALL SELECT '-a' UNION ALL SELECT '-c-b' DECLARE @i INT ,@MaxLen INT SET @maxLen=(SELECT max(LEN(falarm))FROM #t) SET @i=1 WHILE @i<@maxLen BEGIN INSERT INTO #Fala select * from (SELECT SUBSTRING(falarm,@i,2)AS fala FROM #T )a WHERE a.fala!='' SET @i=@i+2 END SELECT * FROM #Fala
谢谢!不过这只是我举得一个例子,我想要的结果是不是单有这几行,有很多行的情况下如何做?如: falarm 1 -abc-ef-cda 2 -gh-ty-ccc 3 -sc-ch 4 -cd-dd 5 -....... . ........ . ........ . ........ . ........ ...
回复
wanglanxuan1 2015-08-27
引用 3 楼 zbdzjx 的回复:
with table1(falarm) as
(
  SELECT '-a-b' UNION ALL
  SELECT '-a-b-c' UNION ALL
  SELECT '-a' UNION ALL
  SELECT '-c-b' 
)
select '-' + falarm falarm from 
(
  SELECT B.falarm FROM 
  (
    SELECT [value] = CONVERT(XML , '<v>' + REPLACE(falarm , '-' , '</v><v>') + '</v>') from table1
  ) A
  OUTER APPLY 
  (
    SELECT falarm = N.v.value('.' , 'varchar(100)') FROM A.[value].nodes('/v') N ( v )
  ) B
) c where falarm <>''
谢谢!不过这只是我举得一个例子,我想要的结果是不是单有这几行,有很多行的情况下如何做?如: falarm 1 -abc-ef-cda 2 -gh-ty-ccc 3 -sc-ch 4 -cd-dd 5 -....... . ........ . ........ . ........ . ........ ...
回复
相关推荐
发帖
疑难问题
创建于2007-09-28

2.1w+

社区成员

MS-SQL Server 疑难问题
申请成为版主
帖子事件
创建了帖子
2015-08-27 08:49
社区公告
暂无公告