求SQL,把各列的值排序后,然后连接成一个字串输出成一个新列!
A1 A2 A3
1 3 2
11 8 4
6 2 1
..........
输出结果(各列横向排序了)
1,2,3
4,3,11
1,2,6
问题点数:100、回复次数:15Top
1 楼libin_ftsafe(子陌红尘:TS for Banking Card)回复于 2006-03-03 15:04:09 得分 0
declare @t table(A1 int,A2 int,A3 int)
insert into @t select 1 ,3,2
insert into @t select 11,8,4
insert into @t select 6 ,2,1
select
case
when A1<=A2 and A1<=A3 then rtrim(A1)
when A2<=A1 and A2<=A3 then rtrim(A2)
else rtrim(A3)
end
+','+
case
when (A1>=A2 and A1<=A3) or (A1>=A3 and A1<=A2) then rtrim(A1)
when (A2>=A1 and A2<=A3) or (A2>=A3 and A2<=A1) then rtrim(A2)
else rtrim(A3)
end
+','+
case
when A1>=A2 and A1>=A3 then rtrim(A1)
when A2>=A1 and A2>=A3 then rtrim(A2)
else rtrim(A3)
end as value
from
@t
/*
value
----------
1,2,3
4,8,11
1,2,6
*/Top
2 楼highscore2(谢谢你的回答:p)回复于 2006-03-03 15:17:34 得分 0
谢谢!libin_ftsafe(子陌红尘)
请问还有没有好一点的方法,因为我些表可能有更多的列, 这样的话上面的方法就很难用了.
我想可能要用游标了,希望高手指点一下Top
3 楼highscore2(谢谢你的回答:p)回复于 2006-03-03 15:23:13 得分 0
学到小技巧 rtrim(A1) 就能把int转成没空格的字符串了. 但不知性能上与 convert(varchar(10),...) 是否一样.Top
4 楼libin_ftsafe(子陌红尘:TS for Banking Card)回复于 2006-03-03 15:32:07 得分 0
--生成测试数据
create table test(A1 int,A2 int,A3 int)
insert into test select 1 ,3,2
insert into test select 11,8,4
insert into test select 6 ,2,1
go
--创建用户定义函数
create function f_str(@A1 int,@A2 int,@A3 int)
returns varchar(40)
as
begin
declare @r varchar(40)
declare @t table(A int)
insert into @t
select @A1
union all select @A2
union all select @A3
set @r=''
select @r=@r+','+rtrim(A) from @t order by A
set @r=stuff(@r,1,1,'')
return @r
end
go
--执行查询
select dbo.f_str(A1,A2,A3) as value from test
go
--输出结果
/*
value
----------
1,2,3
4,8,11
1,2,6
*/
--删除测试数据及用户定义函数
drop function f_str
drop table testTop
5 楼libin_ftsafe(子陌红尘:TS for Banking Card)回复于 2006-03-03 15:32:30 得分 55
--生成测试数据
create table test(A1 int,A2 int,A3 int)
insert into test select 1 ,3,2
insert into test select 11,8,4
insert into test select 6 ,2,1
go
--创建用户定义函数
create function f_str(@A1 int,@A2 int,@A3 int)
returns varchar(40)
as
begin
declare @r varchar(40)
declare @t table(A int)
insert into @t
select @A1
union all select @A2
union all select @A3
set @r=''
select @r=@r+','+rtrim(A) from @t order by A
set @r=stuff(@r,1,1,'')
return @r
end
go
--执行查询
select dbo.f_str(A1,A2,A3) as value from test
go
--输出结果
/*
value
----------
1,2,3
4,8,11
1,2,6
*/
--删除测试数据及用户定义函数
drop function f_str
drop table testTop
6 楼zlp321002(Life Is Good,Let's Shine)回复于 2006-03-03 15:33:11 得分 15
--喜欢用游标?那给你一个写法。
declare @t table(ID int identity(1,1),A1 int,A2 int,A3 int)
insert into @t select 1,3,2
union all select 11,8,4
union all select 6,2,1
declare @id varchar(20)
declare @tb table(列 varchar(200))
declare @s varchar(200)
Declare Cur Cursor For
select ID from @t
Open Cur
Fetch Cur Into @id
While @@FETCH_STATUS=0
BEGIN
set @s=''
select @s=@s+','+cast(T.A as varchar) from (
select A1 as A from @t where id=@id
union all
select A2 as A from @t where id=@id
union all
select A3 as A from @t where id=@id
) T order by A
insert into @tb select stuff(@s,1,1,'')
Fetch Cur Into @id
End
Close Cur
Deallocate cur
--查看结果
select * from @tb
/*
列
----------------
1,2,3
4,8,11
1,2,6
(所影响的行数为 3 行)
*/
Top
7 楼wgsasd311(自强不息)回复于 2006-03-03 15:33:37 得分 5
rtrim(a1)<==>cast(a1 as varchar)<==>convert(varchar,a1)Top
8 楼libin_ftsafe(子陌红尘:TS for Banking Card)回复于 2006-03-03 15:35:19 得分 0
如果列数更多,需要相应的修改用户定义函数入口参数的数目以及insert操作的代码。
另外,注意返回字符串的长度,可以适当的定义得更大一些,同时,内部定义的@r参数长度要与之一致。Top
9 楼lsqkeke(可可)回复于 2006-03-03 15:36:42 得分 10
可以用函数实现:
--用函数实现的话,必须要求你的表有个主键列,
--或唯一值列,假设A1为唯一列
create table tk(A1 int,A2 int,A3 int)
insert into tk select 1,3,2
insert into tk select 11,8,4
insert into tk select 6 ,2,1
go
create function jj(
@i int
)returns varchar(100)
as
begin
declare @tb table(a int)
declare @var varchar(1000)
insert @tb
select @i
union all
select A2 from tk where A1=@i
union all
select A3 from tk where A1=@i
--根据你的表,列出所有的列
set @var=''
select @var=@var+','+cast(a as varchar) from @tb order by a
return stuff(@var,1,1,'')
end
go
--调用
select dbo.jj(A1) from tk
Top
10 楼geniusli(纠级天使)回复于 2006-03-03 16:00:35 得分 0
这样不行,你用A1列当索引列如果A1列有重复的你的程序肯定错。
楼上的写得一点儿都不对Top
11 楼geniusli(纠级天使)回复于 2006-03-03 16:05:35 得分 0
我写一个比较灵活的实现吧,由于sqlserver2000不支持数组的原因,不能用循环处理排序,所以只能多写几个选择来处理排序。
我的方法是冒泡法,我只举个三列数据的例子。
第一句话就是说我这个方法比较灵活,主要是由于即使是四列或五列也会很方便修改。
我在程序后面会说明。
稍等... ...Top
12 楼geniusli(纠级天使)回复于 2006-03-03 16:07:23 得分 15
--终于OK了
create table t1 (A1 int,A2 int,A3 int)
insert into t1 select 1 ,3,2
insert into t1 select 11,8,4
insert into t1 select 6 ,2,1
select * from t1
declare cur_t1 cursor
for select * from t1
open cur_t1
declare @temptable table(resule varchar(100))
declare @a1 int,@a2 int ,@a3 int--当然可以更多个
declare @temp int
fetch next from cur_t1 into @a1,@a2,@a3
WHILE @@FETCH_STATUS = 0
begin
if(@a1>@a2)
begin
set @temp=@a1
set @a1=@a2
set @a2=@temp
end
if(@a2>@a3)
begin
set @temp=@a2
set @a2=@a3
set @a3=@temp
end
if(@a1>@a2)
begin
set @temp=@a1
set @a1=@a2
set @a2=@temp
end
insert into @temptable select rtrim(@a1)+','+rtrim(@a2)+','+rtrim(@a3)
fetch next from cur_t1 into @a1,@a2,@a3
end
close cur_t1
select * from @temptableTop
13 楼highscore2(谢谢你的回答:p)回复于 2006-03-03 16:10:53 得分 0
还是感觉用function 好点! 谢谢! 各位
Top
14 楼highscore2(谢谢你的回答:p)回复于 2006-03-03 16:14:43 得分 0
多给一点 geniusli(纠级天使) 鼓励一下, 用libin_ftsafe(子陌红尘)的思路更好Top
15 楼geniusli(纠级天使)回复于 2006-03-03 16:17:24 得分 0
以上方法用冒泡排序,只是把原来的循环方法给展开成为条件语句。这样的话
n个变量就会有sum(n-1)种条件。
比如3个变量就是sum(3-1)=sum(2)=1+2=3
5个变量就是sum(5-1)=sum(4)=1+2+3+4=10
如果你有五列就需要五个变量,也就是10个条件语句。
像以下代码中
if(@a1>@a2)
begin
set @temp=@a1
set @a1=@a2
set @a2=@temp
end
begin与end语句块之间是交换两个变量的值。
也可以做成函数,但我不知道sql中怎么用引用传递。
如果是5个变量,条件是这样的:
if(@a1>@a2)
begin 变换 end
if(@a2>@a3)
begin 变换 end
if(@a3>@a4)
begin 变换 end
if(@a4>@a5)
begin 变换 end
if(@a1>@a2)
begin 变换 end
if(@a2>@a3)
begin 变换 end
if(@a3>@a4)
begin 变换 end
if(@a1>@a2)
begin 变换 end
if(@a2>@a3)
begin 变换 end
if(@a1>@a2)
begin 变换 end
一共10个条件语句
OK
累晕中,请勿打扰... ...Top




