第十一课
这一课介绍什么是子查询,如何使用它们
主要代码如下:
select cust_name, cust_contact
from Customers
where cust_id in (select cust_id
from Orders
where order_num in (select order_num
from OrderItems
where prod_id = 'RGAN01'));
select cust_name, cust_state,
(select count(*)
from Orders
where Orders.cust_id = Customers.cust_id) as orders
from Customers
order by cust_name;
1. 子查询是嵌套在其他查询中的查询
2. 包含子查询的SELECT语句难以阅读和调试,适当的把子查询分解为多行并进行适当的缩进
3. 作为子查询的SELECT语句只能查询单个列
4. 子查询中的WHERE子句要使用完全限定列名,避免歧义
小结:这一课学习了什么是子查询,如何使用它们。子查询常用于WHERE子句的IN操作符中,以及用来填充计算列
第十二课
这一课会介绍什么是联结,为什么使用联结,如何编写使用联结的SELECT语句
主要代码如下:
select vend_name, prod_name, prod_price
from Vendors, Products
where Vendors.vend_id = Products.vend_id;
select vend_name, prod_name, prod_price
from Vendors inner join Products
on Vendors.vend_id = Products.vend_id;
select prod_name, vend_name, prod_price, quantity
from OrderItems, Products, Vendors
where Products.vend_id = Vendors.vend_id
and OrderItems.prod_id = Products.prod_id
and order_num = 20007;
select cust_name, cust_contact
from Customers
where cust_id in (select cust_id
from Orders
where order_num in (select order_num
from OrderItems
where prod_id = 'RGAN01'));
select cust_name, cust_contact
from Customers, Orders, OrderItems
where Customers.cust_id = Orders.cust_id
and Orders.order_num = OrderItems.order_num
and prod_id = 'RGAN01';
1. 简单说,联结是一种机制,用来在一条SELECT语句中关联表
2. 在引用的列可能出现歧义时,必须使用完全限定列名
3. 要保证所有联结都有WHERE子句,要保证WHERE子句的正确性
4. 目前为止使用的联结称为等值联结,也称为内联结,可以使用稍微不同的语法,明确指定联结的类型
5. 联结的表越多,性能下降的越厉害,不要联结不必要的表
6. 要注意许多DBMS本身限制了联结约束中表的数目
7. 最后的例子说明执行给定的操作一般不止一种方法,有必要试验不同的选择机制,找出最适合的方法
小结:联结是SQL中一个最重要、最强大的特性,有效的使用联结需要对关系数据库设计有基本的了解。本课介绍了等值联结这种最常用的联结
第十三课
这一课讲解另外一些联结(包括它们的含义和使用方法),介绍如何使用表别名,如何对被联结的表使用聚集函数
主要代码如下:
select cust_name, cust_contact
from Customers as C, Orders as O, OrderItems as OI
where C.cust_id = O.cust_id
and oi.order_num = o.order_num
and prod_id = 'RGAN01';
select cust_id, cust_name, cust_contact
from Customers
where cust_name = (select cust_name
from Customers
where cust_contact = 'Jim Jones');
select c1.cust_id, c1.cust_name, c1.cust_contact
from Customers as c1, Customers as c2
where c1.cust_name = c2.cust_name
and c2.cust_contact = 'Jim Jones';
select C.*, O.order_num, O.order_date,
OI.prod_id, OI.quantity, OI.item_price
from Customers as C, Orders as O, OrderItems as OI
where C.cust_id = O.cust_id
and OI.order_num = O.order_num
and prod_id = 'RGAN01';
select Customers.cust_id, Orders.order_num
from Customers inner join Orders
on Customers.cust_id = Orders.cust_id;
select Customers.cust_id, Orders.order_num
from Customers left outer join Orders
on Customers.cust_id = Orders.cust_id;
select Customers.cust_id, Orders.order_num
from Customers right outer join Orders
on Customers.cust_id = Orders.cust_id;
select Customers.cust_id, orders.order_num
from Customers full outer join Orders
on Customers.cust_id = Orders.cust_id;
select Customers.cust_id, count(orders.order_num) as num_ord
from Customers inner join Orders
on Customers.cust_id = Orders.cust_id
group by Customers.cust_id;
select Customers.cust_id, count(orders.order_num) as num_ord
from Customers left outer join Orders
on Customers.cust_id = Orders.cust_id
group by Customers.cust_id;
1. SQL允许给表名起别名,这样做可以缩短SQL语句,还可以允许在一条SELECT语句中多次使用相同的表
2. 自联结通常作为外部语句,用来替代从相同表中检索数据的使用子查询语句,虽然最后的结果往往相同,但大多数情况下,使用联结比使用子查询快得多
3. 自然联结排除多次出现,使每一列只返回一次。自然联结要求只能选择那些唯一的列,一般通过对一个表使用通配符(SELECT*),而对其他表的列使用明确地子集来完成
4. 外联结可以包括没有关联行的那些行
5. 在使用OUTER JOIN语法时,必须使用LEFT或者RIGHT关键字指定包括其所有行的表,可以通过调整表的顺序来改变左右外联结
6. 全外联结可以包含两个表的不关联的行
7. 聚集函数可以方便的和联结一起使用
8. 汇总一下联结及其使用的要点:
- 注意所使用的联结类型,一般我们使用内联结,但使用外联结也有效
- 关于确切的联结语法,应该查看具体的文档,看相应的DBMS支持何种语法
- 保证使用正确的联结条件,否则会返回不正确的数据
- 应该总是提供联结条件
- 在一个联结中可以包含多个表,甚至可以对每个联结采用不同的联结类型。但应该在一起测试它们前分别测试每个联结。这会使故障排除更简单
小结:本课是上一课的延续,首先讲授了如何以及为什么使用别名,然后讨论不同的联结类型以及每类联结所使用的语法。我们还介绍了如何与联结一起使用聚集函数,以及在使用联结时应该注意的问题
第十四课
本课讲述如何利用UNION操作符讲多条SELECT语句组合成一个结果集
主要代码如下:
select cust_name, cust_contact, cust_email
from Customers
where cust_state in ('IL', 'IN', 'MI');
select cust_name, cust_contact, cust_email
from Customers
where cust_name = 'Fun4All';
select cust_name, cust_contact, cust_email
from Customers
where cust_state in ('IL', 'IN', 'MI')
union
select cust_name, cust_contact, cust_email
from Customers
where cust_name = 'Fun4All';
select cust_name, cust_contact, cust_email
from Customers
where cust_name = 'Fun4All'
or cust_state in ('IL', 'IN', 'MI');
select cust_name, cust_contact, cust_email
from Customers
where cust_state in ('IL', 'IN', 'MI')
union all
select cust_name, cust_contact, cust_email
from Customers
where cust_name = 'Fun4All';
select cust_name, cust_contact, cust_email
from Customers
where cust_state in ('IL', 'IN', 'MI')
union
select cust_name, cust_contact, cust_email
from Customers
where cust_name = 'Fun4All'
order by cust_name, cust_contact;
1. 主要有两种情况需要使用组合查询
- 在一个查询中从不同的表返回结构数据
- 对一个表执行多个查询,按一个查询返回数据
2. 多数情况下,组合相同表的两个查询所完成的工作与具有多个WHERE子句条件的一个查询所完成的工作相同。换句话说任何具有多个WHERE子句的SELECT语句都可以作为一个组合查询
3. 可用UNION操作符来组合数条SQL查询,利用UNION,可给出多条SELECT语句,将它们的结果组合成一个结果集
4. 使用UNION组合SELECT语句的数目,SQL没有标准限制,但最好参考一下具体的DBMS文档
5. 实践中应该比较UNION与WHERE,看哪种方法更好
6. 使用UNION应该注意的几条规则
- UNION必须由两条或两条以上的SELECT语句组成,语句之间用关键字UNION分割
- UNION中的每个查询必须包含相同的列、表达式或聚集函数
- 列数据必须兼容:类型不必完全相同,但必须是DBMS可以隐含转换的类型
7. UNION ALL为UNION的一种形式,它完成了WHERE子句完成不了的工作
8. 再用UNION组合查询时,只能使用一条ORDER BY子句,它必须位于最后一条SELECT语句之后
9. 为了简单,本课的例子都是使用UNION来组合针对同一表的多个查询。实际上,UNION在需要组合多个表的数据时也很有用,即使是有不匹配列名的表,在这种情况下,可以将UNION与别名组合,检索一个结果集
小结:这一课讲授如何用UNION操作符来组合SELECT语句。利用UNION,可以把多条查询的结果作为一条组合查询来返回,不管结果中有无重复。使用UNION可极大地简化复杂的WHERE子句,简化从多个表中检索数据的工作