赞
踩
数据查询的一些总结和感想(不全面,主要是连接查询和嵌套查询)
表结构
表结构
student(sno, sname, ssex, sage, sdept)
course(cno, cname, cpno, ccredit)
sc(sno, cno,grade)
select student *,sc* from student,sc where student.sno=sc.sno
[查询每个学生及其选课情况]
# 过程:现在student中找到第一个元组,然后从头到尾开始扫描sc表,一个一个的寻找和第一个元组的sno相同的sc的sno,找到后开始拼接起来。这是一个二重循环。
select maker from products natural join laptops where laptops.hd>=100;
select maker from products join laptops using (model) where laptops.hd>=100;
[查询哪个供应商提供laptop硬盘至少100gb以上的供应商信息]
#过程:自然连接是一种特殊的等值连接,它要求两个关系中进行比较的分量必须是
相同的属性组,并且在结果中把重复的属性列去掉。而等值连接并不去掉重复的属性列。
这也是个二重循环。
select maker from products inner join laptops on products.model=laptops.model
where laptops.hd>=100;
#左外连接:左向外联接的结果集包括 LEFT OUTER子句中指定的左表的所有行,而不仅仅
是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表
的所有选择列表列均为空值。
#右外连接:右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某
行在左表中没有匹配行,则将为左表返回空值。
#全外连接:完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,
则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值
左外连接
select A.*,B.* from A left join B on a.id=b.parent_id
右外连接
select a.*,b.* from a right join b on a.id=b.parent_id
全外连接
select a.*,b.* from a full join b on a.id=b.parent_id
select first.cno,second.cpno from course first, course second where first.cpno=second.cno;
[查询每一门课的间接选修课]
这些东西的原理和二重循环其实是差不多的。思维不要固化,并不一定非得相对应的连接除了自然连接之外。
#子查询的select语句不能使用order by,因为order by 是对最后的结果进行的分类。
相关子查询是从里带外,不相关是从外到里
#不相关子查询
select sno ,sname from student where sdept in
(select sdept from student where sname="刘晨")
[查询与刘晨在同一个系学习的学生]
过程:进行子查询的select的语句,然后成为父查询的条件,从里带外
#相关子查询
select sno, cno from sc x where grade>=(select avg(grade) from sc y where x.sno=y.sno
[查询每个学生超过他自己选修平均成绩的课程号]
过程:从外层查询去一个元组,将元组的sno传递给内层查询,执行内层查询,
然后得到外层查询。从里到外。
数据查询实战练习
查询的题目要求
select count(*) from sales where day=to_day('2013-12-20','yyyy-MM-dd');
select sum(quantity) from sales where day=to_day('2013-12-20','yyyy-MM-dd');
select hd from pcs group by hd having count(*)>=2;
#count(model)的话结果是一样的,但是这是因为巧合原因如果里面有null就不对,但是因为现实因素所以里面并没有空值。我的想法是错误的,在没有count(*)是计算所有的记录没错,但是count(列名)也是,并不是仅仅计算指定列里有几个不一样的值
count()包括了所有的列,相当于行数,在统计结果的时候,不会忽略列值为NULL。
count(列名)只包括列名那一列,在统计结果的时候,会忽略列值为空
count() :统计所有的行数,包括为null的行(COUNT(*)不单会进行全表扫描,也会对表的每个字段进行扫描。而COUNT(‘x’)或者COUNT(COLUMN)或者COUNT(0)等则只进行一个字段的全表扫描)。
#等值连接
select products.maker from products,laptops where products.model=laptops.model and laptops.hd>=100;
#内链接
select maker from products inner join laptops on products.model=laptops.model where laptops.hd>=100;
#自然连接(2种方法)
select maker from products natural join laptops where laptops.hd>=100;
select maker from products join laptops using (model) where laptops.hd>=100;
#子查询
#不相关子查询
select maker from products where model in ( select model from laptops where hd>=100);
#相关子查询
select maker from products where exists (select * from laptops where hd>=100 and model=products.model);
select pcs.model,pcs.price from pcs,products where products.model=pcs.model and products.maker='B' union select laptops.model,laptops.price from laptops,products where products.model=laptops.model and products.maker='B' union select printers.model,printers.price from printers,products where products.model=printers.model and products.maker='B';
#这里的b提供很多不同的商品所以要用union连接起来
select distinct maker from products where maker not in ( select maker from products where type='pc')and type='laptop';(对的)
#这句话的意思是这个供应商必须提供laptop,或者laptop和printer。
select distinct maker from products where type<>'pc'and type<>'laptop' and maker in (select distinct maker from products where type='laptop');(错的)
select distinct maker from products where type<>'pc' and maker in (select distinct maker from products where type='laptop');(错的)
#可以这么想,先找到提供laptop的供应商,然后在从里面找到不提供pc的(这个想法是错的
,如果子查询里面是只提供laptop的供应商的话,那找到的供应商里有提供pc的,所以应该先找到不提供pc的,那找到的就是提供laptop和pc的,这有三种选择,然后在出去只提供printer的).
select x.model,y.model from pcs x,pcs y where x.speed=y.speed and x.ram=y.ram and x.model=y.model and x.model<y.model;
#典型的自身连接
select maker from products,pcs where products.model =pcs.model group by maker having count(*)=3;
select maker from products where type='pc' group by maker having count(*)=3;
#这里的两种做法,有供应商有pc电脑可以想到通过这两个表的等值连接构造出一个买pc电脑的供应商的表,然后在通过group by进行分类,在通过having进行条件过滤。但是由于products表里面有type所以不等值连接也可以。
select maker from products ,pcs where products.model=pcs.model group by maker having count(*)>=3;
查询语句的书写思路:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。