高手们,看看这个SQL问题 ( 积分: 20 )

  • 主题发起人 主题发起人 gxf1681
  • 开始时间 开始时间
G

gxf1681

Unregistered / Unconfirmed
GUEST, unregistred user!
如何用最简单的SQL(最好一句话就可以实现为好)完成如下功能:<br>假设有表:Score<br>//=================<br>pname&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bname&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;score<br>A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Chinese&nbsp;&nbsp;&nbsp; 80.0<br>A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Math&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 70.0<br>A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; EngLish&nbsp;&nbsp;&nbsp; 80.0<br>B&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Computer&nbsp;&nbsp; 120.0<br>要求实现功能:<br>&nbsp;&nbsp;&nbsp;&nbsp;显示结果为:<br>pname&nbsp;&nbsp;bname&nbsp;chinesescore&nbsp;&nbsp;bname&nbsp;&nbsp;mathscore&nbsp;&nbsp;bname&nbsp;&nbsp;englishscore<br>A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chinese&nbsp;&nbsp;&nbsp;80&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;math&nbsp;&nbsp;&nbsp;&nbsp;70&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;english&nbsp;&nbsp;&nbsp;80<br><br>请高手们看看这个问题如何解
 
还是用存储过程吧,<br>这样SQL代码能很清楚,并且运行效率也高.(我自已感觉效率高,无实际考证过)
 
一定要用SQL语句吗?
 
一定要这种横行显示?纵行显示不行?
 
一定要这种横行显示
 
select&nbsp;a.pname,a.bname,a.score,b.bname,b.score,c.bname,c.score<br>from&nbsp;score&nbsp;a,score&nbsp;b,score&nbsp;c<br>where&nbsp;a.bname='chinese'&nbsp;and&nbsp;b.bname='math'&nbsp;and&nbsp;c.bnmae='english'
 
bname,是不确定,不能这样写条件,
 
那就只能写过程了
 
应该是有办法的,
 
先写个函数(作用:把学科和分数并起来)<br>create&nbsp;or&nbsp;replace&nbsp;function&nbsp;f_get_bname_score(var_a1&nbsp;in&nbsp;varchar2)&nbsp;return&nbsp;varchar2&nbsp;is<br>&nbsp;&nbsp;v_Result&nbsp;varchar2(32767);<br>&nbsp;&nbsp;cursor&nbsp;c_bname&nbsp;is<br>&nbsp;&nbsp;&nbsp;&nbsp;select&nbsp;bname,score<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;表名<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where&nbsp;pname&nbsp;=&nbsp;var_a1;<br>begin<br>&nbsp;&nbsp;for&nbsp;cbname&nbsp;in&nbsp;c_bname&nbsp;loop<br>&nbsp;&nbsp;&nbsp;&nbsp;v_Result&nbsp;:=&nbsp;v_Result&nbsp;||cbname.bname||'~'||cbname.score&nbsp;||'/';<br>&nbsp;&nbsp;end&nbsp;loop;<br>&nbsp;&nbsp;return(v_Result);<br>end&nbsp;f_get_bname_score;<br>查询(反复利用Oracle&nbsp;instr和substr函数):<br><br>select&nbsp;pname,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;substr(ChineseScore,&nbsp;1,&nbsp;instr(ChineseScore,&nbsp;'~')&nbsp;-&nbsp;1)&nbsp;as&nbsp;Chinese,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;substr(ChineseScore,&nbsp;instr(ChineseScore,&nbsp;'~')&nbsp;+&nbsp;1,&nbsp;20)&nbsp;as&nbsp;ChineseScore,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;substr(EnglishScore,&nbsp;1,&nbsp;instr(EnglishScore,&nbsp;'~')&nbsp;-&nbsp;1)&nbsp;as&nbsp;English,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;substr(EnglishScore,&nbsp;instr(EnglishScore,&nbsp;'~')&nbsp;+&nbsp;1,&nbsp;20)&nbsp;as&nbsp;EnglishScore,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;substr(MathScore,&nbsp;1,&nbsp;instr(MathScore,&nbsp;'~')&nbsp;-&nbsp;1)&nbsp;as&nbsp;Math,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;substr(MathScore,&nbsp;instr(MathScore,&nbsp;'~')&nbsp;+&nbsp;1,&nbsp;20)&nbsp;as&nbsp;MathScore<br>&nbsp;&nbsp;from&nbsp;(select&nbsp;pname,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--rtrim(a,&nbsp;'/'),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;substr(a,&nbsp;1,&nbsp;instr(a,&nbsp;'/')&nbsp;-&nbsp;1)&nbsp;as&nbsp;ChineseScore,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rtrim(substr(a,&nbsp;-&nbsp;(instr(a,&nbsp;'/'))),&nbsp;'/')&nbsp;as&nbsp;EnglishScore,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--substr(a,instr(a,&nbsp;'/')+1),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;substr(substr(a,&nbsp;instr(a,&nbsp;'/')&nbsp;+&nbsp;1),<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instr(substr(a,&nbsp;instr(a,&nbsp;'/')&nbsp;+&nbsp;1),&nbsp;'/')&nbsp;-&nbsp;1)&nbsp;as&nbsp;MathScore<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;(select&nbsp;distinct&nbsp;pname,&nbsp;f_get_bname_score(pname)&nbsp;as&nbsp;a<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;test_table))<br>缺点:<br>&nbsp;&nbsp;&nbsp;&nbsp;学科是固定3个的,若多于3个需要修改函数和修改查询语句
 
这其实就是转向问题,将纵向数据转为横向的,网上这类代码很多的,楼主可以google一下。
 
用一个循环,读出bname,然后根据bName生成联合sql语句
 
非得用SQL实现横向干嘛哦!<br>程序控制不是更简单!比较pname&nbsp;不一样就另起一行&nbsp;一样就追加<br>要不就用临时表,因为你看情况你的bname是一定的
 
经高手指点,有更好方法:<br>select&nbsp;pname,&nbsp;max(decode(cn,&nbsp;1,&nbsp;bname))&nbsp;bname,&nbsp;max(decode(cn,&nbsp;1,&nbsp;score))&nbsp;ChineseScore,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max(decode(cn,&nbsp;2,&nbsp;bname))&nbsp;bname,&nbsp;max(decode(cn,&nbsp;2,&nbsp;score))&nbsp;EnglishScore,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;max(decode(cn,&nbsp;3,&nbsp;bname))&nbsp;bname,&nbsp;max(decode(cn,&nbsp;3,&nbsp;score))&nbsp;MathScore<br>&nbsp;&nbsp;from&nbsp;(select&nbsp;pname,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bname,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;score,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;row_number()&nbsp;over(partition&nbsp;by&nbsp;pname&nbsp;order&nbsp;by&nbsp;bname)&nbsp;cn<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;test_table&nbsp;t)&nbsp;a<br>group&nbsp;by&nbsp;pname
 
decode,row_number,这两个函数,在SQLServer200并不识别哦,
 
利用游標進行行列互換.&nbsp;支持動態字段.我以前就寫了一個
 
select&nbsp;pname,(case&nbsp;when&nbsp;bname='chinese'&nbsp;then&nbsp;bname&nbsp;else&nbsp;null&nbsp;end)&nbsp;as&nbsp;bname_1,(case&nbsp;when&nbsp;bname='chinese'&nbsp;and&nbsp;score=80&nbsp;then&nbsp;score&nbsp;else&nbsp;null&nbsp;end)&nbsp;as&nbsp;chinesescore,(case&nbsp;when&nbsp;bname='Math'&nbsp;then&nbsp;bname&nbsp;else&nbsp;null&nbsp;end)&nbsp;as&nbsp;bname_2,(case&nbsp;when&nbsp;bname='Math'&nbsp;and&nbsp;score=70&nbsp;then&nbsp;score&nbsp;else&nbsp;null&nbsp;end)&nbsp;as&nbsp;Mathscore,(case&nbsp;when&nbsp;bname='EngLish'&nbsp;then&nbsp;bname&nbsp;else&nbsp;null&nbsp;end)&nbsp;as&nbsp;bname_3,(case&nbsp;when&nbsp;bname='EngLish'&nbsp;and&nbsp;score=80&nbsp;then&nbsp;score&nbsp;else&nbsp;null&nbsp;end)&nbsp;as&nbsp;EngLishscor&nbsp;from&nbsp;Score&nbsp;where&nbsp;pname='A'&nbsp;group&nbsp;by&nbsp;pname<br>看看这个行不行?还没经过测试
 
谢谢各位!
 
多人接受答案了。
 
后退
顶部