免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6011 | 回复: 9
打印 上一主题 下一主题

请教高手 sybase 动态列转行 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-12-09 21:19 |只看该作者 |倒序浏览
--建表
create table tb(   Name    varchar(10) ,   Subject varchar(10) ,   Result  int)
--录入数据
insert into tb(name , subject , result) values('张三' , '语文' , 74)
insert into tb(name , subject , result) values('张三' , '数学' , 83)
insert into tb(name , subject , result) values('张三' , '物理' , 93)
insert into tb(name , subject , result) values('李四' , '语文' , 74)
insert into tb(name , subject , result) values('李四' , '数学' , 84)
insert into tb(name , subject , result) values('李四' , '物理' , 94)

--动态列转行
declare @sql varchar(8000)
set @sql = 'select name as ' + '姓名'  
select @sql = @sql + ' , max(case subject when ''' + subject + ''' then result else 0 end) [' + subject + ']' from (select distinct subject from tb ) as a  
set @sql = @sql + ' from tb group by name'
exec(@sql)

实现结果:

在ms_sql中没有任何问题,结果为  

姓名  数学  物理  语文
李四   84    94    74
张三   83    93    74

但是同样的语句在sybase中执行的结果就是不是自己想要的,其结果为

姓名  物理
张三  93
李四  94

筛选出来的结果只有“物理”一门学科了。本菜鸟以前都是用ms-sql的,最近才开始用sybase,
不理解为什么在ms-sql中可以,为什么到sybase就不行了,请问问题出在哪里,或者在sybase中
动态列转行该怎么实现,请高人不吝指教,小弟在此多谢了,初来乍到,也不知道怎么送分,下次学会了,一定送分,谢谢了!!

论坛徽章:
0
2 [报告]
发表于 2012-12-09 22:20 |只看该作者
嗯?各位大哥大姐,请出手相助啊,小弟先谢谢了!

论坛徽章:
33
ChinaUnix元老
日期:2018-07-04 15:10:362015年亚洲杯之阿联酋
日期:2015-02-06 17:15:532015亚冠之武里南联
日期:2015-06-06 15:40:252015亚冠之北京国安
日期:2015-06-17 15:42:412022北京冬奥会纪念版徽章
日期:2015-08-10 16:30:322015亚冠之阿尔纳斯尔
日期:2015-09-20 09:42:1215-16赛季CBA联赛之北京
日期:2016-01-15 10:03:5915-16赛季CBA联赛之青岛
日期:2016-04-26 16:44:4915-16赛季CBA联赛之广夏
日期:2018-07-04 15:33:21C
日期:2016-10-25 16:12:142017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之同曦
日期:2017-02-22 22:41:10
3 [报告]
发表于 2012-12-10 11:10 |只看该作者
你用第三方工具吧,再说ms-sq与sybase的语法是一样的。

论坛徽章:
0
4 [报告]
发表于 2012-12-10 11:56 |只看该作者
wfcjz 发表于 2012-12-10 11:10
你用第三方工具吧,再说ms-sq与sybase的语法是一样的。



非常感谢“wfcjz”的回答,但是,我的问题是:同样是结构化查询语言,为什么sybase就不行,问题出在哪里?我想直接用sql_script实现,另外你说的第三方工具是指把数据先筛选出到前台然后再处理,还是说直接就有这样的第三方组件(列转行组件)?

论坛徽章:
7
数据库技术版块每日发帖之星
日期:2015-08-09 06:20:00数据库技术版块每日发帖之星
日期:2015-11-03 06:20:00数据库技术版块每日发帖之星
日期:2016-02-20 06:20:00数据库技术版块每日发帖之星
日期:2016-07-13 06:20:00数据库技术版块每日发帖之星
日期:2016-07-31 06:20:00数据库技术版块每日发帖之星
日期:2016-08-01 06:20:00数据库技术版块每日发帖之星
日期:2016-08-18 06:20:00
5 [报告]
发表于 2012-12-10 16:41 |只看该作者
本帖最后由 Eisen 于 2012-12-10 16:55 编辑

原因就在于ms-sql和sybase的 T-SQL语法解析经过10多年的各自演化已经很多地方都不一样了。
你这个差异的原因就在这句话上——
select @sql = @sql + ... from ...

这个在ms-sql上会把(select distinct subject from tb ) as a这里的3行合并成一行,而sybase会保留仍然3行,而取最后一个返回的来定义@sql。
这两种解释方法其实都正确——因为T-SQL的扩展定义里面并未规定在变量赋值有多行结果集时应合并或取首……不过感觉上sybase更严格一些,因为ms-sql上很可能相同的数据,和相同的操作结果形成不同的结果-- 例如 tb里都是 (A,B,C) 但因为每次动态形成的查询计划不同而导致提交结果集各行先后顺序不同最后形成 "姓名  数学  物理  语文"或"姓名  数学  语文  物理"这样都有可能的。
而sybase则要求程序员一定要明确定义出形成新字符串时各row所依的明确定义条件来形成最终结果字符串中的前后位置。

论坛徽章:
0
6 [报告]
发表于 2012-12-10 17:11 |只看该作者
非常感谢“Eisen ”!!原来通过这种论坛的方式,可以接触这么高水平而又乐于分享、奉献的老师们,之前我都是闭门造车,今天是长见识了,谢谢前辈们!你们的指点将会对我产生很大的作用,虽然我没有太看懂你说的意思,但是我会继续研究下去,谢谢“Eisen ”,谢谢老师们!

论坛徽章:
0
7 [报告]
发表于 2012-12-10 17:21 |只看该作者
Eisen 发表于 2012-12-10 16:41
原因就在于ms-sql和sybase的 T-SQL语法解析经过10多年的各自演化已经很多地方都不一样了。
你这个差异的原 ...





请问“Eisen ”老师,那如果我想通过sql脚本在sybase中实现动态列转行,该怎么做呢?可以实现吗?

论坛徽章:
7
数据库技术版块每日发帖之星
日期:2015-08-09 06:20:00数据库技术版块每日发帖之星
日期:2015-11-03 06:20:00数据库技术版块每日发帖之星
日期:2016-02-20 06:20:00数据库技术版块每日发帖之星
日期:2016-07-13 06:20:00数据库技术版块每日发帖之星
日期:2016-07-31 06:20:00数据库技术版块每日发帖之星
日期:2016-08-01 06:20:00数据库技术版块每日发帖之星
日期:2016-08-18 06:20:00
8 [报告]
发表于 2012-12-10 17:38 |只看该作者
不敢称老师……这里强人多了去了……能binary修page link的 hobbylu和andkylee,精擅Sybase全线产品的2BeSybpro,那个sybman更直接就是Sybase的开发人员……都是一等一牛人……叫他们老师吧。
sybase里row -> column一直是个难题,我自己也必须通过cursor或while循环来形成,一般我会把你的(select distinct subject from tb ) as a这里根据需要的排序条件(order by ...) 形成一个identity临时表,然后走cursor或while或并行或串行来形成最终结果字符串。

论坛徽章:
0
9 [报告]
发表于 2012-12-11 11:43 |只看该作者
谢谢“Eisen ”前辈! 和我这个菜鸟比起来,你们都是前辈、老师哦,都值得我学习,谢谢您给我提供思路,真的要经常向前辈们学习啊,还望前辈不吝指教啊。

论坛徽章:
0
10 [报告]
发表于 2012-12-20 10:19 |只看该作者
Eisen解释得很清楚,MS 和Sybase的 T-SQL语法解析现在很多地方不一样了。
在Sybase中可以写一个存储过程来实现,或者用我下面的笨办法。
1> select * from tb
2> go
Name       Subject    Result
---------- ---------- -----------
Zhang San  Chinese             74
Zhang San  Math                83
Zhang San  Physics             93
Li Si      Chinese             74
Li Si      Math                84
Li Si      Physics             94

(6 rows affected)

1> select distinct Name as 'Name',
2> max(case Subject when 'Chinese' then Result end) as Chinese,
3> max(case Subject when 'Math' then Result end) as Math,
4> max(case Subject when 'Physics' then Result end) as Physics
5> from tb
6> group by Name
7> go
Name       Chinese     Math        Physics
---------- ----------- ----------- -----------
Li Si               74          84          94
Zhang San           74          83          93

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP