老革命碰到新问题,行列转换,求指点。

shoppo0505 2014-01-20 06:43:31
之前有个朋友发贴,要求按照自定义的字符,将字符串分割后,存入不同的列。
这个做法有很多种,这里就不一一列举了。
我自己写了个SQL语句,可以不借助函数,临时表等,直接分割字符串。
源数据:
ID date data
----------- ----------------------- ----------------------------
1 2014-01-20 11:36:08.943 1asd 2assd 3asd 4das 5gfsd
2 2014-01-20 11:36:08.943 6asd 7assd 8asd 9das 10agfsd

分割后:
ID date data
--- ----------------------- -------
1 2014-01-20 11:36:44.993 1asd
1 2014-01-20 11:36:44.993 2assd
1 2014-01-20 11:36:44.993 3asd
1 2014-01-20 11:36:44.993 4das
1 2014-01-20 11:36:44.993 5gfs
2 2014-01-20 11:36:44.993 6asd
2 2014-01-20 11:36:44.993 7assd
2 2014-01-20 11:36:44.993 8asd
2 2014-01-20 11:36:44.993 9das
2 2014-01-20 11:36:44.993 10agfs

如何使用SQL语句直接得出如下结果:
ID date data1 data2 data3 data4 data5
--- ----------------------- ------- ------- ------- ------- -------
1 2014-01-20 11:36:44.993 1asd 2assd 3asd 4das 5gfs
2 2014-01-20 11:36:44.993 6asd 7assd 8asd 9das 10agfs

要求不借助函数,临时表任何其他手段,可以动态显示(列数不确定)。
我看了很多资料,也没能像出来怎么写,这里大拿多,所以来问问。
pivot是不能用了,因为列中没有相同值可以分组。
...全文
282 31 打赏 收藏 转发到动态 举报
写回复
用AI写文章
31 条回复
切换为时间正序
请发表友善的回复…
发表回复
zlp321002 2014-01-21
  • 打赏
  • 举报
回复
ID和DATE不是相同列,可以分组吗?
shoppo0505 2014-01-21
  • 打赏
  • 举报
回复
引用 29 楼 zlp321002 的回复:
ID和DATE不是相同列,可以分组吗?
可以,给出代码就行。
shoppo0505 2014-01-21
  • 打赏
  • 举报
回复
看来没人有主意了,先结贴吧。但是分数长期有效。 如果有谁能给出代码。另外开贴发送最高分。
shoppo0505 2014-01-20
  • 打赏
  • 举报
回复
引用 27 楼 yupeigu 的回复:
可以由你的程序来实现,动态语句,然后让数据库执行
个人非常反感拼接数据库语句的做法。 如果上面还有程序,那么肯定不会拼接语句了。更优的方法多的是。 行,这贴到这里算是半结贴状态吧,再等1,2天,看看哪位能人能取走这200分。哈哈
  • 打赏
  • 举报
回复
引用 26 楼 shoppo0505 的回复:
[quote=引用 25 楼 yupeigu 的回复:] [quote=引用 24 楼 shoppo0505 的回复:] [quote=引用 22 楼 yupeigu 的回复:] [quote=引用 21 楼 shoppo0505 的回复:] [quote=引用 18 楼 luckyrandom 的回复:] 何必要执着于一个SQL呢,很多时候将一件事逻辑性地拆分多个步骤亦是正道 若是我,直接SP处理,根本不用思考要单一SQL完成任务
你说的没错。但是前面我说过,正好弄到这里,自己又完成不了,所以上来问问。[/quote] 对了,你的意思是oracle能实现这个功能?[/quote] 不行,也要写全列名。我脑子秀逗了。[/quote] 基本上就只能通过动态语句来实现,通过pivot或者unpivot,好像不能实现,也无法实现动态列名。[/quote] 话说,就是放宽一步来说,即使可以使用除了拼接SQL语句之外的辅助手段,动态列名的问题也不能解决是吧? 如果真不行,我也死心了。其实就像我前面说的,行列转换本就不应该在数据库层面来解决。[/quote] 确实,不通过动态语句,基本上就不太可能实现动态列名。 可以由你的程序来实现,动态语句,然后让数据库执行
shoppo0505 2014-01-20
  • 打赏
  • 举报
回复
引用 25 楼 yupeigu 的回复:
[quote=引用 24 楼 shoppo0505 的回复:] [quote=引用 22 楼 yupeigu 的回复:] [quote=引用 21 楼 shoppo0505 的回复:] [quote=引用 18 楼 luckyrandom 的回复:] 何必要执着于一个SQL呢,很多时候将一件事逻辑性地拆分多个步骤亦是正道 若是我,直接SP处理,根本不用思考要单一SQL完成任务
你说的没错。但是前面我说过,正好弄到这里,自己又完成不了,所以上来问问。[/quote] 对了,你的意思是oracle能实现这个功能?[/quote] 不行,也要写全列名。我脑子秀逗了。[/quote] 基本上就只能通过动态语句来实现,通过pivot或者unpivot,好像不能实现,也无法实现动态列名。[/quote] 话说,就是放宽一步来说,即使可以使用除了拼接SQL语句之外的辅助手段,动态列名的问题也不能解决是吧? 如果真不行,我也死心了。其实就像我前面说的,行列转换本就不应该在数据库层面来解决。
  • 打赏
  • 举报
回复
引用 24 楼 shoppo0505 的回复:
[quote=引用 22 楼 yupeigu 的回复:] [quote=引用 21 楼 shoppo0505 的回复:] [quote=引用 18 楼 luckyrandom 的回复:] 何必要执着于一个SQL呢,很多时候将一件事逻辑性地拆分多个步骤亦是正道 若是我,直接SP处理,根本不用思考要单一SQL完成任务
你说的没错。但是前面我说过,正好弄到这里,自己又完成不了,所以上来问问。[/quote] 对了,你的意思是oracle能实现这个功能?[/quote] 不行,也要写全列名。我脑子秀逗了。[/quote] 基本上就只能通过动态语句来实现,通过pivot或者unpivot,好像不能实现,也无法实现动态列名。
shoppo0505 2014-01-20
  • 打赏
  • 举报
回复
引用 22 楼 yupeigu 的回复:
[quote=引用 21 楼 shoppo0505 的回复:] [quote=引用 18 楼 luckyrandom 的回复:] 何必要执着于一个SQL呢,很多时候将一件事逻辑性地拆分多个步骤亦是正道 若是我,直接SP处理,根本不用思考要单一SQL完成任务
你说的没错。但是前面我说过,正好弄到这里,自己又完成不了,所以上来问问。[/quote] 对了,你的意思是oracle能实现这个功能?[/quote] 不行,也要写全列名。我脑子秀逗了。
shoppo0505 2014-01-20
  • 打赏
  • 举报
回复
引用 20 楼 yupeigu 的回复:
[quote=引用 19 楼 shoppo0505 的回复:] 游标也是属于其他手段啊。 正好做到这里,实在想不出来该怎么做。所以上来问问,感觉肯定有什么东西我还不知道的。 SQL中没有CONCAT这类字符串操作函数阿。郁闷
concat和sql server中的+号效果是一样的,关键是这个也不能实现动态的效果的把[/quote] 你说的没错。 对于数字有SUM之类函数,但是字符串没有啊。我是这个意思。 动态行转列,我写好了。琢磨着,反着回过去应该也行吧? 但是好像动态列名不好弄。pivot就是这个问题。
  • 打赏
  • 举报
回复
引用 21 楼 shoppo0505 的回复:
[quote=引用 18 楼 luckyrandom 的回复:] 何必要执着于一个SQL呢,很多时候将一件事逻辑性地拆分多个步骤亦是正道 若是我,直接SP处理,根本不用思考要单一SQL完成任务
你说的没错。但是前面我说过,正好弄到这里,自己又完成不了,所以上来问问。[/quote] 对了,你的意思是oracle能实现这个功能?
shoppo0505 2014-01-20
  • 打赏
  • 举报
回复
引用 18 楼 luckyrandom 的回复:
何必要执着于一个SQL呢,很多时候将一件事逻辑性地拆分多个步骤亦是正道 若是我,直接SP处理,根本不用思考要单一SQL完成任务
你说的没错。但是前面我说过,正好弄到这里,自己又完成不了,所以上来问问。
  • 打赏
  • 举报
回复
引用 19 楼 shoppo0505 的回复:
游标也是属于其他手段啊。 正好做到这里,实在想不出来该怎么做。所以上来问问,感觉肯定有什么东西我还不知道的。 SQL中没有CONCAT这类字符串操作函数阿。郁闷
concat和sql server中的+号效果是一样的,关键是这个也不能实现动态的效果的把
shoppo0505 2014-01-20
  • 打赏
  • 举报
回复
游标也是属于其他手段啊。 正好做到这里,实在想不出来该怎么做。所以上来问问,感觉肯定有什么东西我还不知道的。 SQL中没有CONCAT这类字符串操作函数阿。郁闷
Q315054403 2014-01-20
  • 打赏
  • 举报
回复
何必要执着于一个SQL呢,很多时候将一件事逻辑性地拆分多个步骤亦是正道 若是我,直接SP处理,根本不用思考要单一SQL完成任务
  • 打赏
  • 举报
回复
引用 15 楼 shoppo0505 的回复:
[quote=引用 14 楼 yupeigu 的回复:] [quote=引用 13 楼 shoppo0505 的回复:] [quote=引用 12 楼 yupeigu 的回复:] [quote=引用 11 楼 shoppo0505 的回复:] [quote=引用 10 楼 DBA_Huangzj 的回复:] 听说大奖是iphone5,不过估计没份了……只有500元的自助餐……
有比没有好。 偶只有13个月的死工资。[/quote] 还是你比较好,去年记得摸奖,什么也没摸到,就发了一瓶洗发水。 有一个人摸到一个iphone 5. [/quote] 兄弟,13个月死工资还比较好?其他啥都没有的哦。年终奖也没有的啊。 洗发水也是用钱买的啊。别把旺仔小馒头不当干粮。[/quote] 呵呵,说的也有道理。 对了,我写了一个,你看看是不是这样:

drop table tb
go

create table tb(ID int,date datetime,data varchar(1000))

                        
insert into tb
select 1   ,'2014-01-20 11:36:08.943', '1asd 2assd 3asd 4das 5gfsd' union all  
select 2   ,'2014-01-20 11:36:08.943', '6asd 7assd 8asd 9das 10agfsd'
go

declare @sql varchar(8000)

set @sql = ''

;with t
as
(
select id,
       date,
       SUBSTRING(replace(t.data,' ',','), number ,
                 CHARINDEX(',',replace(t.data,' ',',')+',',number)-number) as data,
       ROW_NUMBER() over(partition by id,date order by @@servername) rownum
from tb t,master..spt_values s
where s.number >=1
and s.type = 'P'
and SUBSTRING(','+replace(t.data,' ',','),s.number,1) = ','
)

select @sql = @sql + 
            ',max(case when rownum = '+CAST(rownum as varchar) + 
            ' then data else null end) as [data'+CAST(rownum as varchar)+']'
from t
group by rownum


select @sql = ';with t
			as
			(
			select id,
				   date,
				   SUBSTRING(replace(t.data,'' '','',''), number ,
							 CHARINDEX('','',replace(t.data,'' '','','')+'','',number)-number) as data,
				   ROW_NUMBER() over(partition by id,date order by @@servername) rownum
			from tb t,master..spt_values s
			where s.number >=1
			and s.type = ''P''
			and SUBSTRING('',''+replace(t.data,'' '','',''),s.number,1) = '',''
			)'+
            'select id,date'+@sql+
            'from t group by id,date'
            
exec( @sql)
/*
id	date	data1	data2	data3	data4	data5
1	2014-01-20 11:36:08.943	1asd	2assd	3asd	4das	5gfsd
2	2014-01-20 11:36:08.943	6asd	7assd	8asd	9das	10agfsd
*/
[/quote] 说了,不借助其他手段。拼接字符串也属于其他手段。 如果拼接字符串,直接replace字符为 "as 列名,"就ok,不用你这么麻烦。[/quote] 得动态行转列,但不能用动态语句,这个好像没办法实现的吧。
發糞塗牆 2014-01-20
  • 打赏
  • 举报
回复
那貌似只有游标咯,需要这么苛刻吗?
shoppo0505 2014-01-20
  • 打赏
  • 举报
回复
引用 14 楼 yupeigu 的回复:
[quote=引用 13 楼 shoppo0505 的回复:] [quote=引用 12 楼 yupeigu 的回复:] [quote=引用 11 楼 shoppo0505 的回复:] [quote=引用 10 楼 DBA_Huangzj 的回复:] 听说大奖是iphone5,不过估计没份了……只有500元的自助餐……
有比没有好。 偶只有13个月的死工资。[/quote] 还是你比较好,去年记得摸奖,什么也没摸到,就发了一瓶洗发水。 有一个人摸到一个iphone 5. [/quote] 兄弟,13个月死工资还比较好?其他啥都没有的哦。年终奖也没有的啊。 洗发水也是用钱买的啊。别把旺仔小馒头不当干粮。[/quote] 呵呵,说的也有道理。 对了,我写了一个,你看看是不是这样:

drop table tb
go

create table tb(ID int,date datetime,data varchar(1000))

                        
insert into tb
select 1   ,'2014-01-20 11:36:08.943', '1asd 2assd 3asd 4das 5gfsd' union all  
select 2   ,'2014-01-20 11:36:08.943', '6asd 7assd 8asd 9das 10agfsd'
go

declare @sql varchar(8000)

set @sql = ''

;with t
as
(
select id,
       date,
       SUBSTRING(replace(t.data,' ',','), number ,
                 CHARINDEX(',',replace(t.data,' ',',')+',',number)-number) as data,
       ROW_NUMBER() over(partition by id,date order by @@servername) rownum
from tb t,master..spt_values s
where s.number >=1
and s.type = 'P'
and SUBSTRING(','+replace(t.data,' ',','),s.number,1) = ','
)

select @sql = @sql + 
            ',max(case when rownum = '+CAST(rownum as varchar) + 
            ' then data else null end) as [data'+CAST(rownum as varchar)+']'
from t
group by rownum


select @sql = ';with t
			as
			(
			select id,
				   date,
				   SUBSTRING(replace(t.data,'' '','',''), number ,
							 CHARINDEX('','',replace(t.data,'' '','','')+'','',number)-number) as data,
				   ROW_NUMBER() over(partition by id,date order by @@servername) rownum
			from tb t,master..spt_values s
			where s.number >=1
			and s.type = ''P''
			and SUBSTRING('',''+replace(t.data,'' '','',''),s.number,1) = '',''
			)'+
            'select id,date'+@sql+
            'from t group by id,date'
            
exec( @sql)
/*
id	date	data1	data2	data3	data4	data5
1	2014-01-20 11:36:08.943	1asd	2assd	3asd	4das	5gfsd
2	2014-01-20 11:36:08.943	6asd	7assd	8asd	9das	10agfsd
*/
[/quote] 说了,不借助其他手段。拼接字符串也属于其他手段。 如果拼接字符串,直接replace字符为 "as 列名,"就ok,不用你这么麻烦。
  • 打赏
  • 举报
回复
引用 13 楼 shoppo0505 的回复:
[quote=引用 12 楼 yupeigu 的回复:] [quote=引用 11 楼 shoppo0505 的回复:] [quote=引用 10 楼 DBA_Huangzj 的回复:] 听说大奖是iphone5,不过估计没份了……只有500元的自助餐……
有比没有好。 偶只有13个月的死工资。[/quote] 还是你比较好,去年记得摸奖,什么也没摸到,就发了一瓶洗发水。 有一个人摸到一个iphone 5. [/quote] 兄弟,13个月死工资还比较好?其他啥都没有的哦。年终奖也没有的啊。 洗发水也是用钱买的啊。别把旺仔小馒头不当干粮。[/quote] 呵呵,说的也有道理。 对了,我写了一个,你看看是不是这样:

drop table tb
go

create table tb(ID int,date datetime,data varchar(1000))

                        
insert into tb
select 1   ,'2014-01-20 11:36:08.943', '1asd 2assd 3asd 4das 5gfsd' union all  
select 2   ,'2014-01-20 11:36:08.943', '6asd 7assd 8asd 9das 10agfsd'
go

declare @sql varchar(8000)

set @sql = ''

;with t
as
(
select id,
       date,
       SUBSTRING(replace(t.data,' ',','), number ,
                 CHARINDEX(',',replace(t.data,' ',',')+',',number)-number) as data,
       ROW_NUMBER() over(partition by id,date order by @@servername) rownum
from tb t,master..spt_values s
where s.number >=1
and s.type = 'P'
and SUBSTRING(','+replace(t.data,' ',','),s.number,1) = ','
)

select @sql = @sql + 
            ',max(case when rownum = '+CAST(rownum as varchar) + 
            ' then data else null end) as [data'+CAST(rownum as varchar)+']'
from t
group by rownum


select @sql = ';with t
			as
			(
			select id,
				   date,
				   SUBSTRING(replace(t.data,'' '','',''), number ,
							 CHARINDEX('','',replace(t.data,'' '','','')+'','',number)-number) as data,
				   ROW_NUMBER() over(partition by id,date order by @@servername) rownum
			from tb t,master..spt_values s
			where s.number >=1
			and s.type = ''P''
			and SUBSTRING('',''+replace(t.data,'' '','',''),s.number,1) = '',''
			)'+
            'select id,date'+@sql+
            'from t group by id,date'
            
exec( @sql)
/*
id	date	data1	data2	data3	data4	data5
1	2014-01-20 11:36:08.943	1asd	2assd	3asd	4das	5gfsd
2	2014-01-20 11:36:08.943	6asd	7assd	8asd	9das	10agfsd
*/
shoppo0505 2014-01-20
  • 打赏
  • 举报
回复
引用 12 楼 yupeigu 的回复:
[quote=引用 11 楼 shoppo0505 的回复:] [quote=引用 10 楼 DBA_Huangzj 的回复:] 听说大奖是iphone5,不过估计没份了……只有500元的自助餐……
有比没有好。 偶只有13个月的死工资。[/quote] 还是你比较好,去年记得摸奖,什么也没摸到,就发了一瓶洗发水。 有一个人摸到一个iphone 5. [/quote] 兄弟,13个月死工资还比较好?其他啥都没有的哦。年终奖也没有的啊。 洗发水也是用钱买的啊。别把旺仔小馒头不当干粮。
  • 打赏
  • 举报
回复
引用 11 楼 shoppo0505 的回复:
[quote=引用 10 楼 DBA_Huangzj 的回复:] 听说大奖是iphone5,不过估计没份了……只有500元的自助餐……
有比没有好。 偶只有13个月的死工资。[/quote] 还是你比较好,去年记得摸奖,什么也没摸到,就发了一瓶洗发水。 有一个人摸到一个iphone 5.
加载更多回复(11)

22,207

社区成员

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

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