后返回结果集,如果表数据量大的话可能会导致用磁盘进行排序。
而UNIONALL只是简单的将两个结果合并后就返回。这样,如果返回的两个结果集中有重复的数据,那么返回的结果集就会包含重复的数据了。
从效率上说,UNIONALL要比UNION快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据的话,那么就使用UNIONALL,3.分页语句
取出sql表中第31到40的记录(以自动增长ID为主键)sqlserver方案1:
selecttop10*fromtwhereidnotin(selecttop30idfromtorderbyid)ordebyidsqlserver方案2:
selecttop10*fromtwhereidin(selecttop40idfromtorderbyid)orderbyiddescmysql方案:select*fromtorderbyidlimit30,10
oracle方案:select*from(selectrownumr,*fromtwherer<=40)wherer>30--------------------待整理进去的内容-------------------------------------pageSize=20;pageNo=5;
1.分页技术1(直接利用sql语句进行分页,效率最高和最推荐的)
mysql:sql=\*fromarticleslimit\+(pageNo-1)*pageSize+\+pageSize;oracle:sql=\*from\+
\rownumr,*from\+
\*fromarticlesorderbypostimedesc)\+\rownum<=\+pageNo*pageSize+\tmp\+\r>\+(pageNo-1)*pageSize;
注释:第7行保证rownum的顺序是确定的,因为oracle的索引会造成rownum返回不同的值
简洋提示:没有orderby时,rownum按顺序输出,一旦有了orderby,rownum不按顺序输出了,这说明rownum是排序前的编号。如果对orderby从句中的字段建立了索引,那么,rownum也是按顺序输出的,因为这时候生成原始的查询结果集时会参照索引表的顺序来构建。
sqlserver:sql=\top10*fromidnotid(selecttop\+(pageNo-1)*pageSize+\fromarticles)\
DataSourceds=newInitialContext().lookup(jndiurl);Connectioncn=ds.getConnection();
//\*fromuserwhereid=?\--->binarydirectivePreparedStatementpstmt=cn.prepareSatement(sql);ResultSetrs=pstmt.executeQuery()while(rs.next())
{
out.println(rs.getString(1));}
2.不可滚动的游标pageSize=20;pageNo=5;cn=nullstmt=null;rs=null;try{
sqlserver:sql=\
*fromarticles\
DataSourceds=newInitialContext().lookup(jndiurl);Connectioncn=ds.getConnection();
//\*fromuserwhereid=?\--->binarydirectivePreparedStatementpstmt=cn.prepareSatement(sql);ResultSetrs=pstmt.executeQuery()for(intj=0;j<(pageNo-1)*pageSize;j++){
rs.next();}inti=0;
while(rs.next()&&i<10){
i++;
out.println(rs.getString(1));}}
cacth(){}finnaly{
if(rs!=null)try{rs.close();}catch(Exceptione){}if(stm.........if(cn............}
3.可滚动的游标pageSize=20;pageNo=5;cn=null
stmt=null;rs=null;try{
sqlserver:sql=\
*fromarticles\
DataSourceds=newInitialContext().lookup(jndiurl);Connectioncn=ds.getConnection();
//\*fromuserwhereid=?\--->binarydirectivePreparedStatementpstmt=cn.prepareSatement(sql,ResultSet.TYPE_SCROLL_INSENSITIVE,...);
//根据上面这行代码的异常SQLFeatureNotSupportedException,就可判断驱动是否支持可滚动游标
ResultSetrs=pstmt.executeQuery()rs.absolute((pageNo-1)*pageSize)inti=0;
while(rs.next()&&i<10){
i++;
out.println(rs.getString(1));}}
cacth(){}finnaly{
if(rs!=null)try{rs.close();}catch(Exceptione){}if(stm.........if(cn............}
3.用一条SQL语句查询出每门课都大于80分的学生姓名namekechengfenshu张三语文81张三数学75李四语文76李四数学90王五语文81王五数学100王五英语90
准备数据的sql代码:
createtablescore(idintprimarykeyauto_increment,namevarchar(20),subjectvarchar(20),scoreint);
insertintoscorevalues
(null,'张三','语文',81),(null,'张三','数学',75),(null,'李四','语文',76),(null,'李四','数学',90),(null,'王五','语文',81),(null,'王五','数学',100),(null,'王五','英语',90);
提示:当百思不得其解时,请理想思维,把小变成大做,把大变成小做,答案:
A:selectdistinctnamefromscorescore<=80)
wherenamenotin(selectdistinctnamefromscorewhere
B:selectdistincenamet1fromscorewhere80 一个叫department的表,里面只有一个字段name,一共有4条纪录,分别是a,b,c,d,对应四个球对,现在四个球对进行比赛,用一条sql语句显示所有可能的比赛组合.答:selecta.name,b.namefromteama,teambwherea.name 4.每个月份的发生额都比101科目多的科目请用SQL语句实现:从TestDB数据表中查询出所有月份的发生额都比101科目相应月份的发生额高的科目。请注意:TestDB中有很多科目,都有1-12月份的发生额。AccID:科目代码,Occmonth:发生额月份,DebitOccur:发生额。数据库名:JcyAudit,数据集:Select*fromTestDB准备数据的sql代码:droptableifexistsTestDB; createtableTestDB(idintprimarykeyauto_increment,AccIDvarchar(20),Occmonthdate,DebitOccurbigint); insertintoTestDBvalues(null,'101','1988-1-1',100),(null,'101','1988-2-1',110),(null,'101','1988-3-1',120),(null,'101','1988-4-1',100),(null,'101','1988-5-1',100),(null,'101','1988-6-1',100),(null,'101','1988-7-1',100),(null,'101','1988-8-1',100); --复制上面的数据,故意把第一个月份的发生额数字改小一点insertintoTestDBvalues (null,'102','1988-1-1',90),(null,'102','1988-2-1',110),(null,'102','1988-3-1',120),(null,'102','1988-4-1',100),(null,'102','1988-5-1',100),(null,'102','1988-6-1',100),(null,'102','1988-7-1',100),(null,'102','1988-8-1',100); --复制最上面的数据,故意把所有发生额数字改大一点insertintoTestDBvalues(null,'103','1988-1-1',150),(null,'103','1988-2-1',160),(null,'103','1988-3-1',180),(null,'103','1988-4-1',120),(null,'103','1988-5-1',120),(null,'103','1988-6-1',120),(null,'103','1988-7-1',120),(null,'103','1988-8-1',120); --复制最上面的数据,故意把所有发生额数字改大一点insertintoTestDBvalues(null,'104','1988-1-1',130),(null,'104','1988-2-1',130),(null,'104','1988-3-1',140),(null,'104','1988-4-1',150),(null,'104','1988-5-1',160),(null,'104','1988-6-1',170),(null,'104','1988-7-1',180),(null,'104','1988-8-1',140); --复制最上面的数据,故意把第二个月份的发生额数字改小一点insertintoTestDBvalues(null,'105','1988-1-1',100),(null,'105','1988-2-1',80),(null,'105','1988-3-1',120),(null,'105','1988-4-1',100),(null,'105','1988-5-1',100),(null,'105','1988-6-1',100),(null,'105','1988-7-1',100),(null,'105','1988-8-1',100);答案: selectdistinctAccIDfromTestDBwhereAccIDnotin (selectTestDB.AccIDfromTestDB, (select*fromTestDBwhereAccID='101')asdb101 whereTestDB.Occmonth=db101.OccmonthandTestDB.DebitOccur<=db101.DebitOccur