SQLSERVER用无中生有的思想来替代游标

SQLSERVER用无中生有的思想来替代游标,第1张

概述昨天在MSDN论坛看到一个帖子,帖子中LZ需要根据某列的值把其他列的值插入到额外列 帖子地址:http://social.technet.microsoft.com/Forums/zh-CN/3eac78ca-d071-4c00-afa0-ef48c8501745/sql-statementcolumn-namecolumnsql- 建表脚本:   View Code 图1 LZ说原表就是类似上面

昨天在MSDN论坛看到一个帖子,帖子中LZ需要根据某列的值把其他列的值插入到额外列

帖子地址:http://social.technet.microsoft.com/Forums/zh-CN/3eac78ca-d071-4c00-afa0-ef48c8501745/sql-statementcolumn-namecolumnsql-


建表脚本

  VIEw Code

图1

LZ说原表就是类似上面那样,实际表中pay_lv_会有很多列至少100列,我这里为了测试只建了25个pay_lv_列

而LZ希望select出来的结果是下图那样

 

图2

clIEnt列和pay_level列不变,增加一个pay_cost列

pay_cost列根据pay_level列的值去取pay_lv_列的值,或者我用下面的图片会更加明白

 

图3

例如第6行,pay_level的值是6,那么就去pay_lv_6这一列的值(值是20)把他放到pay_cost列里

其他也是一样,第二行pay_level的值是10,那就去pay_lv_10这一列的值(值是17)把他放到pay_cost列里

如此类推


要select出图2的结果,有下面几种方法

1、case when

2、UNPIVOT函数

3、游标

我这里再建另外一个表,这个表跟原表是一样的,只是数据没有那么多,pay_lv_列数只有3列

  (1)case when

1 SELECT  clIEnt,[pay_level],( CASE pay_level2                   WHEN @H_404_107@1 THEN pay_lv_13                   @H_404_107@2 THEN pay_lv_24                   @H_404_107@3 THEN pay_lv_35                   ELSE @H_404_107@06                 END) AS 'pay_cost'7 FROM    #t;

图4

(2)UNPIVOT函数

1
SELECT * INTO #tt 2 FROM ( SELECT * 3 FROM #t 4 ) p UNPIVOT 5 ( pay_cost FOR pay_lv IN ( pay_lv_1,pay_lv_2,pay_lv_3 ) )AS unpvt 6 WHERE CAST(RIGHT(pay_lv,@H_404_107@1) AS INT) = pay_level 7 8 SELECT clIEnt] FROM #tt] 9 10 DROP table ]

图5

上面两个方法:CASE WHEN和UNPIVOT函数可以用拼接sql的方法来做,不过由于本人功力不够,写不出来

(3)游标

 我不喜欢使用游标,主要有两个原因

1、每次用的时候,要打开笔记本看语法

2、占用资源

 我使用了下面的SQL语句来解决LZ的问题

IF object_ID(#ttt') IS NOT NulLtable #ttt 3 #temptb 4 table #temptb 5 DECLARE @i INT 7   --用于循环的SET @i = @H_404_107@1 9 @pay_level 10   保存pay_level字段的值11 @COUNT 12    保存#t1表的总行数值13 @pay_lv 14   用于保存pay_lv的值15 @sql NVARCHAR(@H_404_107@2000)16 17 CREATE table #ttt (ID INT IDENTITY(@H_404_107@1,0)">@H_404_107@1),pay_cost INT )18 19 SELECT  IDENTITY( INT,0)">@H_404_107@1 ) AS ID,255)">INTO    #temptb FROM  t120 21 22 获取#t1表的总行数23 SELECT  @COUNT = COUNT(*) FROM    24 WHILE <= @COUNT 25     BEGIN26         @pay_level WHERE   ID = @i27     判断列名是否存在,不存在就插入028         pay_lv_' + CAST(VARCHAR(@H_404_107@200)) IN ( SELECT   name FROM     SYS.syscolumns] ) 29             30                 用拼接sql的方法来获得pay_lv列对应的值,然后插入到#ttt表31                 @sql = Nselect  @pay_lv=pay_lv_ from #temptb where ID=@H_404_107@20))32                 EXEC sp_executesql @sql,N@pay_lv   int   output ',@pay_lv OUTPUT33                 INSERT  INTO #ttt VALUES  (@pay_lv)34             END35         ELSE 36             37                 VALUES(@H_404_107@0)38             39         + 40     41 42 43 44 SELECT  A.45 AS A46 INNER JOIN AS B ON A.ID] = B.47 ORDER BY A.ASC48 49 50 ]


我这个SQL语句也需要拼接sql来达到LZ想要的效果

不过这篇文章的重点不是拼接sql


重点是怎麽模仿游标

其实这个方法是最原始的方法,之前解决论坛问题的时候用过,想不到这次也能用上

 
关键代码有以下几句

2
4 5 7 --------------------------------12 14 ASC

 

原表是没有自增ID的,我建一个临时表#temptb,临时表有一个自增ID,并把原表的数据全部放入临时表

获取临时表的行数,用于循环

每次执行的时候根据 WHERE   ID = @i 来逐行逐行获取值,变量@i每次循环都递增1

将获取到的值都插入到#ttt这个临时表里面,然后根据ID的值做两表连接就可以得到LZ的结果

我说的无中生有就是“在原表里增加一个自增ID方便循环,既简单又容易理解o(∩_∩)o ”

 


判断

我这里还用了一句

] )

用于判断要获取值的pay_lv_列是否存在,如果存在就插入pay_lv_列的值,如果不存在就插入0


总结

其实如果觉得某样东西很难去实现,能不能用一个变通的方法呢?多动脑筋,办法会有的

如有不对的地方,欢迎大家拍砖o(∩_∩)o

总结

以上是内存溢出为你收集整理的SQLSERVER用无中生有思想来替代游标全部内容,希望文章能够帮你解决SQLSERVER用无中生有的思想来替代游标所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/sjk/1170624.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存