SQL 行列转换问题,请高手指点。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL 行列转换问题,请高手指点。相关的知识,希望对你有一定的参考价值。

declare @sql varchar(8000)
set @sql = 'select Products'
select @sql=@sql+',max(case material when '''+material +''' then quantity else 0 end) ['+material +']'
from (select distinct material from scll) as a
set @sql = @sql + ' from scll group by Products'
exec(@sql)
以上代码运行时总是报错,print(@sql)后发现是由于material字段的数据太多,导致生成的语句太长变量空间不足造成的,有什么办法解决这个问题,请高手指点。谢谢!
要转换成行的数据总共为325个,也就是说转换后有325列,加上Products'列共326,print(@sql)后发现,生成的语句不完整,select Products,max(case material when material1 then quantity else 0 end) [material ],
max(case material when material2 then quantity else 0 end) [material2 ]....依次进行,但到第58个时语句就不完整了,没有end,以及后面的列名直接加上了from scll group by Products
,有办法解决这个问题吗?

该问题的关键是SQL Server 2000字段大小限制了。
有个笨的办法,将325个物料分成两组(如果还不够,分成3组),用你这种方法分别进行行列转换,放入临时表,然后将临时表连接起来。

如果是SQL Server 2005就好办了,直接将@sql申明成varchar(max)就行了,它最大支持2GB,应该可以解决此问题。另外,SQL Server 2005专门针对行列转换,有了pivot子句。
参考技术A 根据筛选列生成了新的数据行。
例如
select dz,[男]=sum(case when xb='男' then sl else 0 end),
[女]=sum(case when xb='女' then sl else 0 end)
from table1 group by dz
根据table1 中的数据行xb 分成了男女两列数据。
参考技术B 看你的样子是列转行,SQL每个版本都有相应的列限制,如果超出限制列你得想其它方法来处理

就算用别的方法来处理,select 最多支持4096个列,我想也不可以无限制地增加
参考技术C 我刚才试了一下你的方法,应该是可行的。
方法如下:
declare @sql varchar(8000)
set @sql = 'select page_type'
select @sql=@sql+',max(case updateTime when '''+updateTime +''' then updateTime else null end) ['+updateTime +']'
from (select distinct updateTime from userpage) as a
set @sql = @sql + ' from userpage group by page_type'
exec(@sql)
我个人觉得应该是的material 字段值超出了1024吧。
建议使用print(@sql)试一下,再减少一下字段试一试吧。追问

我写在问题中那段代码是可行的,列转为行后,造成列太多,所以报错,减少字段后试了是可以了,如果我不减少有没有什么好的办法?

追答

你发一下你的sql语句我看一下print(@sql),是否超过了8000,空讲不知道啊。

初学.net,请高手指点

关于这一句:comm.Parameters.AddWithValue("@name", (TextBox)GridView1.Rows[e.RowIndex].Cells[1].Controls[0].Text)的几个问题:
1.AddWithValue()函数怎么用?msdn上说“向 SqlParameterCollection 的末尾添加值。”太抽象了。我理解是不是把第二个参数的值赋给第一个参数的意思?
2.@的含义,是变量的标志吗?
3."Rows[e.RowIndex].cells[1].Controls[0]"中括号的用法
4.cells、controls的含义
谢谢!

你这句comm本身有一条SQL语句吧,这条SQL语句,你去看,你们会有"@name"这样的字符串,这是为了方便使用AddWithValue而留得位置。
AddWithValue意思是,将参数2的内容填充到 comm的SQL语句的 参数1 的位置
也就是用参数2取代”@name” ,LZ明白了吧
AddWIthValue的好处是,不需要考虑填充内容的类型(免去了 打引号 , 打 N''的麻烦)
-----------------------------------------------------------------------------------------------------------------------
3 GridView.Rows是一个数组,表示GridView1这个控件的行的集合。
数组的话,你知道括号的意思吧
4 cells表示 GridView的某一行的某一列位置上的单元格。
比如 GridView1.Rows[0].Cells[1] 就是GridView1控件上的第0行第1列的单元格
.Controls[0]表示取这个单元格上的第一个控件 (一般指的就是取表示这个单元格的控件,一般有TextBox,CheckBox等)
参考技术A 1,是你那样理解,第二个参数给第一个参数赋值,不过@参数要是数据库中的变量
2,数据库中的变量
3,Row(行).cells[格].Controls[第n个子控件]
4,<1>,cells,英语翻译为细胞,你就可以想象为格子,比如把一行分为3格,cells[1]就是第二格,理解为列我觉得不太好。
<2>,controls,这是控件的集合,怎么说呢,girdview生成以后,有一个仅且一个控件,这控件就是个大表格,controls[0]就是这是这个大表格控件。一般来说你只要不要嵌套容器像Gridview.Datagrid等这样的控件的话,controls[0]是不会出错的,但是如果你在容器里面又放了
Gridview.Datagrid等容器,你想引用子容器里面的值,那么就得controls[0].controls[0]了。如果还嵌套,就要controls[2]甚至controls[3]等等了。
另外说controls[0]是textbox、chencbox是不对的
如果我什么地方说错了,还望指正,交流下。
谢谢
参考技术B 1.是间接赋给第一个参数
2.是变量,不过是sqlServer中的变量
3.GridView你就把他当成WebControls.Table的升级版本,你的代码中指的是:第e.RowIndex+1行(Rows).第2列(Cells).中的第1个服务器控制项(Control).第几的几比索引大1,毕竟一般从1说起,而代码是从0开始。
4.Cells指所有列,Controls只控制项集合

以上是关于SQL 行列转换问题,请高手指点。的主要内容,如果未能解决你的问题,请参考以下文章

Oracle 表格行列转换,高手请进

sql行列转换和累加问题~~~

sql server行列转换问题

还是SQL行列转换问题~~

oracle 行列转换问题

sql动态实现行列转换