索引index(相当于创建目录)
优点:提高查询效率。
缺点:占空间,并且添加、更新、删除数据的时候同步更新索引,会降低insert、update、delete的速度。在where上创建索引。
预读取:提前预测执行,然后在查询实际使用这些页时将在缓冲区高速缓存。
逻辑读取:从缓存中读取数据。
物理读取:从硬盘中读取数据。
打开:查询--查询选项--高级--勾上最后两个(如下所示)
--子查询:把查询出来的虚表(结果集)作为原始表,再次进行查询,如下,括号里面的就是子查询语句
select * from (select * from stuInfo_new where java>80 or java<60)as s where gender='男';
--独立子查询:子查询语句可以单独执行的,就是独立子查询,如上,就是独立子查询。
--相关子查询: 子查询语句不可以单独执行,而是依靠外部查询条件一并执行的,就是相关子查询。
select MAX(english) from stuInfo_new union all
select min(english) from stuInfo_new union all
select avg(english) from stuInfo_new;
select (select MAX(english) from stuInfo_new),
(select MIN(english) from stuInfo_new),
(select avg(english) from stuInfo_new);
--子查询如果是多个结果,前面不能用=
select * from stuInfo_new where java in (60,70);
select * from stuInfo_new where stuInfo_new.id=test.id;
select * from stuInfo_new where exists(select * from test where stuInfo_new.id=test.id );
总结:=只能对应1个,你只能单行多列。
--(执行顺序)先执行外部的from 然后按照sql执行顺序执行到子查询语句的时候,子查询才执行
----------------------------分页------------------------
《一》--分页方式一:
-- 原理:子查询中查询出之前已经读过的所有数据,然后外部查询全表所有数据中不包含子查询中的数据,然后取前N(N是每页几条)条
-- 方式一是传统写法,现在已经过时了,现在都用方式二
select top(5) * from stuInfo_new;
select * from stuInfo_new order by java desc;
(任选3个写即可)
①--查询第1页的数据
select top(5) * from stuInfo_new where java not in (select top(5*(1-1)) java from stuInfo_new order by java desc) order by java desc;
②--查询第2页的数据
select top(5) * from stuInfo_new where java not in (select top(5*(2-1)) java from stuInfo_new order by java desc) order by java desc;
③--查询第3页的数据
select top(5) * from stuInfo_new where java not in (select top(5*(3-1)) java from stuInfo_new order by java desc) order by java desc;
select * from stuInfo_new order by id asc;
④--查询第7页数据
select * from stuInfo_new order by id;
select top(5) * from stuInfo_new where id not in (select top(5*(4-1)) id from stuInfo_new order by id desc) order by id desc;
⑤--查询最后一页的数据
select top(5) * from stuInfo_new where id not in (select top(5*(7-1)) id from stuInfo_new order by id) order by id;
----------------------------开窗函数-----------------------------
1、--聚合函数只能显示一行,需要显示所有行时用到开窗函数。
select *,java平均分=AVG(java) over() from stuInfo_new;
select gender ,AVG(java) over() from stuInfo_new ;
2、--需求:后面加一列,显示男女各自的java平均分
select *,java平均分=AVG(java) over(partition by gender) from stuInfo_new;
3、--row_number()函数:给每一行加序号,但是要告诉数据库,怎么加行号,按什么顺序加,所以用到了开窗函数over(),并且通过over()告诉row_number()按什么列排序
select *,行号=ROW_NUMBER() over(order by java) from stuInfo_new;
--有了序号之后,分页就更简单了
4、--查第2页
select * from stuInfo_new where id between (5*(2-1)+1) and (5*2) order by id;
5、--查第3页
select * from stuInfo_new where id between (5*(3-1)+1) and (5*3) order by id;
6、--查第4页
select * from stuInfo_new where id between (5*(4-1)+1) and (5*4) order by id;
delete from stuInfo_new where name like '高帅';
7、--这个案例告诉我们:按照序号来查,很方便,思路也很清晰,但是我们是把id当成序号了,而id不可靠,它有可能没有严格的按照一定的顺序来,有可能少了或者多了,或者跳了好几步,那怎么解决呢?就需要我们自己加一列百分之百可靠的序号(简单来说查询时id不严谨,为了解决id缺增问题,需加一列可靠的序号)--引用ROW_NUMBER()。
select *,序号=ROW_NUMBER() over(order by english desc) from stuInfo_new;
《二》--分页方式二:
原理:给原表加一个个序号列,这个序号列是稳定可靠的,不会漏,也不会多,也不会跳,然后把这个加完列的虚表作为原表被外部语句查询就行了(首先给原表加可靠的序号列,然后把加完列的虚表作为原表被外部语句查询)
1、-- 外部语句如何查询呢?就是用between and来选择你要查的页的开始行和结束行就行了
2、--需求,按照方式二来查询第5页数据
select * from (select *,序号=ROW_NUMBER() over(order by java desc) from stuInfo_new) as t where t.序号 between (5*(5-1)+1) and (5*5) order by t.序号;
3、--需求:按照方式一来查询第7页的数据
select top(5) * from stuInfo_new where id not in (select top(5*(7-1)) id from stuInfo_new order by id) order by id;
4、--需求:按照方式一来查询第2页的数据
select top(5) * from stuInfo_new where java not in (select top(5*(2-1)) java from stuInfo_new order by java) order by java ;
select * from stuInfo_new order by java;
update stuInfo_new set java=96 where name like '张梦%';
delete from stuInfo_new where name like '刘书%';
insert into stuInfo_new values('20160505','41108219956565363','伍子胥','男',40,100,0,'1990-4-3','13536669999','楚国');
5、--需求:取第3页的数据,每页10条 , 要求用第二种方式。
select * from stuInfo_new order by id;
select * from (select *,序号=ROW_NUMBER() over(order by id) from stuInfo_new) as haha where haha.序号 between (10*(3-1)+1) and (10*3) order by haha.序号;
6、--分页注意:我们学了两种方式,第一种已经过时了,并且有漏洞(当外部查询not in子查询的时候,可能会出现漏数据的情况),是不严谨,建议第二种。但是再注意:这两种方式都是sqlserver中的,而mysql和oracle数据库用的都不是这两种方式,但是原理相通,而且更简单,特别是mysql,一步搞定(select * from 表名 limit(10*(3-1)+7))
7、--需求:后面加一列,显示男女各自的java平均分
①--解决方法:在开窗函数里面分组,而不是在后面用group by 分组,记住一句话就可以了,一旦用刀over(),就不要用group by,而是用partition by
select *,男女各自平均分=AVG(java) over(partition by gender) from stuInfo_new;
②--不允许使用开窗函数,实现上面需求
select * from stuInfo_new as t1 inner join (select gender,AVG(java) as java平均分 from stuInfo_new group by gender) as t2 on t1.gender=t2.gender;
select * from stuInfo_new t1 ,(select gender,AVG(java) as java平均分 from stuInfo_new group by gender) as t2 where t1.gender=t2.gender;