CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
IBM Rational 系统开发最佳实践工具包 WebSphere MQ 最佳实践 TOP 15
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  MS-SQL Server >  基础类

求SQL,把各列的值排序后,然后连接成一个字串输出成一个新列!

楼主highscore2(谢谢你的回答:p)2006-03-03 14:55:24 在 MS-SQL Server / 基础类 提问

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

相关问题

  • 输出按数据窗口的某一列排序,如何写?
  • SQL排序
  • sql 排序
  • sql排序
  • sql排序
  • sql排序
  • sql排序
  • VB中如何在SQL语句中使用排序查询以供数据报(Data Report)输出使用?
  • Grid按列排序
  • 求一排序SQL

关键词

  • 排序
  • 函数
  • 语句
  • beginset
  • 变量
  • rtrim
  • tk
  • cur
  • 值
  • varchar

得分解答快速导航

  • 帖主:highscore2
  • libin_ftsafe
  • zlp321002
  • wgsasd311
  • lsqkeke
  • geniusli

相关链接

  • SQL Server类图书

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo