最近在学习列转行,在网上看了很多例子,还是没完全弄懂,自己临时建的一个表
表名tstu
name       kec       scores
张三      语文       98
张三      数学       23
张三      物理       89
李四      语文       89
李四      数学       56
李四      物理       57下面的SQL语句是我找到觉得比较简单,很实用的,可能对初学者有帮助
select* from tstu pivot(max(corde)for kec in(语文,数学,物理))a  //静态SQL查询declare @sql varchar(8000)        //动态SQL查询
set @sql=''   
select @sql=@sql+','+kec from tstu group by kec 
set @sql=stuff(@sql,1,1,'') 
set @sql='select * from tstu pivot (max(corde) for kec in ('+@sql+'))a'
exec(@sql)现在我碰到的问题是, 我需要查询的表有很多列,我只需要其中的几列然后转换成行,用上面的方法也行不通,。。好比你把上面的表tstu再添加一列,但是添加的这一列我不需要查询出来,select*当然不对啦,
而且我要查询的是子表,是把一个子表的列转换成行,我把子表的查询语句直接替换tstu也不对。。 这是为什么呢,, 求大神详解 

解决方案 »

  1.   

    沙发自己做 没人来吗?corde打错了,就是    scores
      

  2.   

    要加个where条件来筛选咯,或者你先弄个中间结果然后再行转列
      

  3.   

    1.行转列?实际应用太少遇得到,展示技术还行,实际应该没什么大用.
    2.用拼语句的方式使用行转列?效率太低了,不如好好琢磨如何建一些更优化的表.
    3.除了数据库外,你不是还有你的程序设计,有些东西,用SQL不一定好,而在你用你的程序设计语言里,根本就不是个问题,基本算法而已.
      

  4.   

    动态拼接sql
      

  5.   

     大神无处不在呀,, 加个where条件来筛选?不会耶, 我还是菜鸟, 大神能否给出SQL语句?
      

  6.   

    2005以后的用法,仅仅是举例:
    declare @sql varchar(8000)        //动态SQL查询
    set @sql='' 
    ;with huang as 
    (
    select 你需要的列名
    from tb
    )  
    select @sql=@sql+','+kec from huang group by kec 
    set @sql=stuff(@sql,1,1,'') 
    set @sql='select * from huang pivot (max(corde) for kec in ('+@sql+'))a'
    exec(@sql)
      

  7.   

    行转列是为了实在没办法时的处理,的确不要随便用,效率很低。所以首先应该先考虑设计表。如果实在没办法(逼近目前的dbms还是关系数据库,是二维的),那才用行转列
      

  8.   


    可能我上面没表达很清楚吧,大神的这段语句跟
    declare @sql varchar(8000)        //动态SQL查询
    set @sql=''   
    select @sql=@sql+','+kec from tstu group by kec 
    set @sql=stuff(@sql,1,1,'') 
    set @sql='select * from tstu pivot (max(corde) for kec in ('+@sql+'))a'
    exec(@sql)  也就是我上面的效果是一样的吧,,不过我的问题是如果这个表里有很多列,但我只是要把其中的三或几列列转成行,select 星号就不行啦。
      

  9.   

    我的意思是,先在with里面把你需要转换的3列取出来,放到一个中间集里面,然后后面的代码只对中间集操作,这样就算select *都没所谓,你试过没?
      

  10.   


    这样呀, sorry, 我刚没看明白,,我试试
      

  11.   

    奈何会报错,,错误 :列名不存在,, 。。 我是给tstu 表添加了一个字段 teacher,然后把name ,kec替换到 “ 你需要的列名”处。。要不大神你直接给出SQL语句给我吧,
      

  12.   

    消息 252,级别 16,状态 1,第 3 行
    递归公用表表达式 'tstu' 不包含顶级 UNION ALL 运算符。
      

  13.   

    下面例子我特意多加了一列,由于cte只能用一次,所以这里我用#t来替代了。--CREATE TABLE tstu(name VARCHAR(10),      kec VARCHAR(10),      scores INT ,test INT)
    --INSERT INTO tstu
    --SELECT '张三',      '语文' ,      98,1
    --UNION ALL
    --SELECT '张三',      '数学' ,      23,1
    --UNION ALL
    --SELECT '张三',      '物理' ,      89,1
    --UNION ALL
    --SELECT '李四',      '语文' ,      89,1
    --UNION ALL
    --SELECT '李四',      '数学' ,      56,1
    --UNION ALL
    --SELECT '李四',     '物理' ,      57,1 
    declare @sql varchar(max)      
    set @sql='' 
     
    select NAME,kec,scores INTO #t
    from tstuselect @sql=@sql+','+kec from #t group by kec 
    set @sql=stuff(@sql,1,1,'') 
    set @sql='select * from #t pivot (max(scores) for kec in ('+@sql+'))a'
    --PRINT @sql
    exec(@sql)
      

  14.   

    就是那个with,2005引入的新功能之一,在联机丛书搜:cte 就有解释了。