五 数据库考点

一、查询语句执行顺序

  查询语句执行顺序from->where->group by->having->select->order by

  当同时含有where子句、group by 子句 、having子句及聚集函数时,执行顺序如下:
--执行where子句查找符合条件的数据;
--使用group by 子句对数据进行分组;对group by 子句形成的组运行聚集函数计算每一组的值;最后用having 子句去掉不符合条件的组。

--在返回集字段要么包含在Group By语句的后面,作为分组的依据;要么就要被包含在聚合函数中。
--having 子句中的每一个元素也必须出现在select列表中。(如2题)有些数据库例外,如oracle.
--having子句和where子句都可以用来设定限制条件以使查询结果满足一定的条件限制。
--having子句限制的是组,而不是行。where子句中不能使用聚集函数,而having子句中可以。

二、例题

1、列出各个部门中工资高于本部门的平均工资的员工数和部门号,并按部门号排序。 

create table emp(
id int primary key auto_increment,
name varchar(50),
salary bigint,
deptin int
);
insert into emp values(null,'zs',1000,1),(null,'ls',1100,1),(null,'ww',1100,1),(null,'zl',900,1),
(null,'zs2',1000,2),(null,'ls2',900,2),(null,'ww2',1000,2),(null,'zl2',900,2);

错误写法:salary不能放在having子句中!
select deptin, count(*) from emp group by deptin having salary>avg(salary) order by deptin;

正确写法:

select emp.deptin, count(*) from emp, (select deptin,avg(salary) avg from emp group by deptin) temp
where emp.deptin=temp.deptin and salary>avg
group by emp.deptin order by emp.deptin;

2、用一条SQL语句查出每门课都大于80分的学生姓名。

create table score(
id int primary key auto_increment,
name varchar(20),
subject varchar(20),
score int
);
insert into score values
(null,'zs','语文',81),
(null,'zs','数学',75),
(null,'ls','语文',76),
(null,'ls','数学',90),
(null,'ww','语文',81),
(null,'ww','数学',100),
(null,'ww','英语',90);

错误语句:
select high.name from (select distinct name from score where score>80) high,(select distinct name from score where score<=80) low
where high.name!=low.name;

正确语句:

select distinct name from score t where 80<all(select score from score where name = t.name) ;//相关子查询

select distinct name from score where name not in (select distinct name from score where score<=80);

3、球队比赛组合。

create table team(
id int primary key auto_increment,
name varchar(8)
);
insert into team values(null,'a'),(null,'b'),(null,'c'),(null,'d');

错误写法:

select t1.name, t2.name from team t1,team t2 where t1.name!=t2.name;//没有去掉ab ba的重复情况

正确写法:select t1.name, t2.name from team t1,team t2 where t1.name>t2.name;

4、 从TestDB数据表中查询出所有月份的发生额都比101科目相应月份的发生额高的科目。(会做)

       请注意:TestDB中有很多科目,都有1-12月份的发生额。
                  AccID:科目代码,Occmonth:发生额月份,DebitOccur:发生额。
                  数据库名:JcyAudit,数据集:Select * from TestDB
                  准备数据的sql代码:
                  drop table if exists TestDB;
                  create table TestDB(id int primary key auto_increment,AccID 
                  varchar(20), Occmonth date, DebitOccur bigint);
                  insert into TestDB values 
                  (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);
                  --复制上面的数据,故意把第一个月份的发生额数字改小一点
                  insert into TestDB values 
                  (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);
                  --复制最上面的数据,故意把所有发生额数字改大一点
                  insert into TestDB values 
                  (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);
                  --复制最上面的数据,故意把所有发生额数字改大一点
                  insert into TestDB values 
                  (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);
                  --复制最上面的数据,故意把第二个月份的发生额数字改小一点
                  insert into TestDB values 
                  (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);

select distinct AccID from testDB where AccID not in(
select testDB.AccID from testDB , (select * from testDB where AccID = 101) temp
where testDB.Occmonth = temp.Occmonth and testDB.DebitOccur <= temp.DebitOccur);

三、存储过程和触发器

四、数据库三范式

五、数据库优化

六、union和union all的区别

union进行表链接后会对结果集排序,删除重复记录再返回结果;

union all只是简单将两个结果合并后就返回,不去重。

union all比union高效,所以如果可以确认合并的两个结果集中不包含重复数据,则用union all。

七、分页(取出第31-40条记录)

1、mysql

select * from t order by id limit 30,10;

2、oracle

select * from (select rownum r, * from (select * from t order by id ) t1 where r<=40) where r>30;

原文地址:https://www.cnblogs.com/seven7seven/p/3938873.html