SQL必知必会-读书笔记(14-17章)

十四、使用子查询

注意事项

#子查询的嵌套数量没有限制

#子查询时,需保证SELECT语句具有与WHERE子句中相同数量的列

1.利用子查询进行过滤

例子:当前有三个表 orders,orderitems,customers

orders:订单号(主键)、订单日期、订单客户ID(关联customers的cust_id)




order by 导致查询慢 怎么解决Using filesort order by 子查询_order by 子查询


orderitems:订单编号(主键),订单物品号(主键)


order by 导致查询慢 怎么解决Using filesort order by 子查询_子查询_02


customers:客户ID(主键)


order by 导致查询慢 怎么解决Using filesort order by 子查询_主键_03


问题:需要列出订购物品TNT2(prod_id)的所有客户名称(cust_name,cust_contanct),需要怎样检索?

(1)检索所有包含TNT2的订单编号(order_num)

(2)检索前一步获得订单编号的所有客户ID(cust_id)

(3)检索前一步返回的所有客户ID的客户名称(cust_name,cust_contanct)

##在关系表中,首先需要确认的就是各个表的关系,各个表的关系是通过键完成的。

  • 分步查询
SELECT


  • 子查询

以终为始的查询方法,撰写时进行倒推。

最终目标(cust_name,cust_contanct)放在最开始进行SELECT。

不同表的链接处WHERE _SELECT刚好对应。


SELECT


2.作为计算字段使用子查询

问题:显示customers表中每个客户的订单总数。(##注意审题喔,不是orders表中的每一个客户)

(1)从customers中检索出客户的列表

(2)对于检索出的每个客户,统计其在order表中的订单数目


SELECT


其中orders 是一个计算字段,它是由圆括号中的子查询建立的。

概念:相关子查询(correlated subquery)——涉及外部查询的子查询

其中orders.cust_id=customers.cust_id 的方式进行了完全限定的表达方式,这样可以避免由于多义导致的含糊不清楚。究竟索引的是哪个表中的cust_id.

——————————————————————————————————————

十五、联结表

1.关系表

主键(primary key):一列(或一组列),其值能够唯一区分表中每个行;

外键(foreign key):某个表中的一列,它包含另一个表的主键值,定义了两个表的关系。

关系数据库

——信息不重复,不浪费时间和空间

——信息变动后,只需修改一处

——数据无重复,数据一致

可伸缩性(scale)

能够适应不断增加的工作量而不失败。设计良好的数据库或应用程序称之为可伸缩性好。

2.创建联结

规定要连接的所有表以及他们如何关联即可。请看下面的例子


SELECT


可以看到给出例子的特别之处在于

(1)SELECT子句中的vend_name来自vendors表,prod_name,prod_price来自products表

(2)FROM中有两个表vendors,products

联结:vendors.vend_id=products_vend_id(完全限定,避免二义)

注意:如果缺少WHERE子句限定条件vendors.vend_id=products_vend_id,则会返回叉联结(cross join)的笛卡尔积的联结类型。这通常不是我们想要的结果。

3.内部联结【交集】

又称为等值联结(equijoin),它基于两个表之间的相当测试。

内连接( [inner] join)是从查询结果表中删除与其他被连接表中没有匹配行的所有行,所以内连接可能会丢失信息。


SELECT


这种表述和上面的表述都是可以的,但是该种表述保障不会忘记联结条件。且能够保障性能。

4.联结多个表

SQL中对一条SELECT语句能够联结表的数目没有限制。


SELECT


还记得下面这个问题么?

问题:需要列出订购物品TNT2(prod_id)的所有客户名称(cust_name,cust_contanct),需要怎样检索?


SELECT


我们如何用联结的方式解题呢?


SELECT


有木有觉得很好用呢!

——————————————————————————————————————

十六、高级联结

1.使用表别名

用途:缩短SQL语句

允许在单条SELECT语句中多次使用相同的表


SELECT


2.不同类型的联结

2.1自联结

问题:假设你发现某物品(ID为DTNTR)存在问题,因此想知道生成该物品的供应商生产的其它物品是否也存在这些问题。

  • 子查询方法
SELECT


  • 联结方法
SELECT


2.2自然联结

通过MySql自己的判断完成连接过程,不需要指定连接条件。MySql会使用表内的,相同的字段,作为连接条件。

自然联结的前提条件是,两个表中至少应该有一列是相同的。


SELECT


附加natural时,表示名称相同的列进行内连接,此时不能使用on...using...等修饰。自然联结是内连接的一种特殊情况。

2.3 外联结【并集】 OUT JOIN

与内连接的区别在于,外连接不仅返回匹配的行,也会返回不匹配的行。

在使用外联结时,必须使用RIGHT 或LEFT管强磁来定义如何联结

(1)左外连接(left outer join):结果集包括 LEFT OUTER子句中指定的左表的所有行,而不仅仅是连接列所匹配的行。如果左表的某行在右表中没有匹配行,则在结果集的行中右表的所有选择列表列均为空值(null)。

(2)右外连接(right outer join):与左连接相反。结果集包括 right OUTER子句中指定的

右表的所有行,而不仅仅是连接列所匹配的行。如果右表的某行在左表中没有匹配行,则在

结果集的行中左表的所有选择列表列均为空值(null)。


SELECT


2.4 带聚集函数的联结

问题:如果要检索所有客户及每个客户所下的订单数


SELECT


______________________________________________________________________________________________

十七、组合查询 UNION

什么时候用到组合查询?

单个查询从不同表返回类似结构的数据;

对单个表执行多个查询,按单个查询返回数据。

UNION规则

(1)必须由两条或两条以上的SELECT语句组成,语句之间用关键字UNION分隔。

(2)每个查询必须包含相同的列、表达式或聚集函数(不要求顺序相同)

(3)合并列的数据类型必须相同或者可以隐含转化的类型

(4)会自动去除重复的行,如果要取消去重,需要使用UNION ALL

(5)ORDER BY只容许在语句最后使用,对所有数据进行排序


SELECT