一、分组查询
1.group by 分组字段1[,分组字段2,…] [having 分组后的筛选条件]
2.注:分组字段应该与select后的查询字段一致,否则查询结果无意义。同时group by之后如果还需要条件进行筛选,要与having一起使用,不用where(分组查询经常会与聚合函数一起使用)
聚合函数:
max(字段名):计算某一字段中的最大值;
min(字段名):计算某一字段中的最小值;
avg(字段名):计算某一字段中的平均值;
sum(字段名):计算某一字段中的字段值的和;
count(字段名):计算某一字段中值不为null的记录总数;
count(*):计算表中的总记录数,无论是否为null;
接下来举一个商品表的例子来对分组查询做一下复习,商品表中有商品id,商品名,商品价格,商品数量和商品类型,最后查询时按类型查询即可
下面为创建表和插入数据的部分:
第一题:计算每件商品单价的平均价格
第二题:计算日用品的平均价格:
二、连接查询
1.等值连接
select 字段1,字段2,…from 表A,表B,…where 连接条件[其他过滤条件];
2.内链接
select 字段1,字段2,…from 表A inner join 表B on 连接条件[其他过滤条件];
等值连接和内连接的作用是一样的,查询出来的结果也是一样的
接下来创建一个学校表和学生表来看一下内连接查询的效果:
一、查询学生的姓名,年龄与所在的学校与学校的备注(等值连接与内连接)
3.外连接(是在内连接的基础上做的稍加改动的查询)
左外连接:select 字段1,字段2,… from 表A left join 表B on 连接条件;
注:左外连接的查询结果是:除了返回表中符合条件的记录外,还要加上左表中剩下的全部的指定字段的记录(再向学校表中插入一条记录,学生表不动)
右外连接:
select 字段1,字段2,…from 表A right join 表B on 连接条件;
右外连接的查询结果为除了返回表中符合连接条件的记录外,还要加上右表中剩下的全部记录,和左外连接恰好相反,这里就不写sql语句了。
三、嵌套查询(子查询)
子查询是指在外部查询语句中嵌套一个内部查询(子查询),子查询的查询结果一般是作为外部查询的条件,子查询的语句要用括号括起来。
子查询常用的关键字:
in:判断某个(些)字段值是否在子查询的结果集中;
all:判断某个字段值是否能满足指定操作符对子查询结果集所有记录的筛选;
any:判断某个字段值是否满足指定操作符对子查询结果的任意一个值。
接下来对Oracle表中自带的emp表中数据来个子查询:
– 查询与SCOTT同一个部门的员工
如果只有一个scott:
select * from emp where deptno=(select deptno from emp where ename=’SCOTT’);
如果至少有一个SCOTT(再插入一条SCOTT的记录):
select * from emp where deptno in(select deptno from emp where ename=’SCOTT’);
–工资高于JONES的员工:
如果只有一个JONES:
select * from emp where sal>(select sal from emp where ename=’JONES’);
如果至少有一个JONES(再添加一条JONSE的记录):
select * from emp where sal>(select max(sal) from emp where ename=’JONES’);
–工资高于30号部门所有的员工的员工信息
方式一:select * from emp where sal>all(select sal from emp where deptno=30);
方式二:select * from emp where sal>(select max(sal) from emp where deptno=30);
–查询工作和工资与MARTIN完全相同的员工信息
查询只有一个员工名叫’MARTIN‘时:
select * from emp where (job,sal)=(select job,sal from emp where ename=’MARTIN’);
当有多个MARTIN时(再插入一条Martin的记录):
select * from emp where (job,sal) in (select job,sal from emp where ename=’MARTIN’);
–查询奖金不为null的员工记录:
select * from emp where comm is not null;
–在emp表中查询,要求查询每个员工的姓名与他对应的上司的名字(可以对一张表的两个有关系的字段进行连接查询):
select e1.ename as 员工姓名,e2.ename as 上司姓名 from emp as e1 left join emp as e2 on e1.mgr=e2.empno;
四、外键(foreign key)
通过外键约束来保证表与表之间的完整性。外键的作用是用来约束子表中的记录,使之与父表的记录相对应。
外键的定义:[constraint 约束名称] foreign key(这个是作为外键的约束名称) references 父表名称(父表主键名)。
通过在字表上设外键的方式,关联父表的主键,这样,父表的一条记录可以关联字表的多条记录。
父表:被外键引用的表;
子表:引用父表的键作为外键的表;
这里需要注意一点,一旦子表在设计时添加了以父表的主键作为子表的外键后,在删除记录时会有一定的限制,如果子表中某些记录中的外键值为父表中的主键值的话,那么不能删除父表的含有这些值的记录,因为一旦在删除时,子表中的外键约束便会起作用了,因此这里说两个挺重要的东西:
1.级联删除:如果主表中的记录删除,那么同时在子表中相对应的记录也会被删除。(格式:在设置完外键之后接着写: on delete cascade)
2.更新时级联:如果主表中的某条记录中被子表外键引用的字段值发生改变,那么子表中相应的记录也会改变(格式:在设置完外键之后接着写: on update cascade,删除时级联和更新时级联可以同时设置)
刚才在写SQL语句时已经用到了外键,外键的使用使的表与表之间的关系更加具有逻辑性,在用到代码时也更加的方便。
五、’一对多’、’多对多‘关系表的设计
在实际运用当中,不同类型的表之间也会有一定的联系,比如学校表和学生表,公司表与部门表之间的关系等,在数据库设计时也要考虑到几张表之间的关系,其中,’一对多‘、’多对多‘的表关系在设计十分的常见。
’一对多‘关系表设计
从字面意思上就可以得知:’一对多’的关系表的意思是,作为父表的一条记录可以关联子表中的多条记录,子表的一条记录却只能对应父表中的唯一一条记录,这很常见啊,比如学校表和学生表,一个学校可以有多个学生,但一个学生只能对应一个学校。在上面学习连接查询时的两张表正是一对多关系表的体现,这里不再过多赘述,例子只是简单理解了一下,真正遇到问题还得是见招拆招,多多去思考才能去真正体会。
‘多对多’关系表设计
在现实生活中,‘多对多’的关系甚至是更加普遍,两个不具有主外键关系的表也会有一定的关系,比如学生表和科目表,一个学生可以修多门科目,一个科目也供多个学生选择;这便是多对多关系的体现。
在设计‘多对多’关系表时,通过设置中间表的方式实现‘多对多’关系的设计,中间表至少含有两个键,分别关联于两张’多’表的主键,而且这两个外键字段的组合值不能重复(可把这两个字段一起作为中间表的联合主键)
接下来就设计一个学生表,科目表和中间表,来感受下多对多表。
如此便设计出了一个多对多关系的表。
向表中添加几条数据:
再向中间表中添加数据:
–查询学号为2的学生选的课程
select stu.stuname as 学生姓名,sub.suname as 课程名 from student as stu inner join subject as sub student_subject on stu.stuid=2 and subid in(select subject_id from student_subject where student_id=2);
以上。