《联结表》
1.联结
(1)关系表
外键(foreign key) 外键为某个表中的一列,它包含另一个表 的主键值,定义了两个表之间的关系。
关系数据可以有效地存储和方便地处理。因此,关系数据库 的可伸缩性远比非关系数据库要好。
可伸缩性(scale) 能够适应不断增加的工作量而不失败。设 计良好的数据库或应用程序称之为可伸缩性好。
(2)为什么要使用联结表?
分解数据为多个表能更有效地存储,更方便地处理,并 且具有更大的可伸缩性。但这些好处是有代价的。
如果数据存储在多个表中,怎样用单条SELECT语句检索出数据?
答案是使用联结。简单地说,联结是一种机制,用来在一条SELECT 语句中关联表,因此称之为联结。使用特殊的语法,可以联结多个表返 回一组输出,联结在运行时关联表中正确的行。
创建联结
下面的联结方式都称为等值联结或内部联结。
联结的创建非常简单,规定要联结的所有表以及它们如何关联即可。 请看下面的例子:
笛卡儿积(cartesian product) 由没有联结条件(没有使用where子句进行过滤)的表关系返回 的结果为笛卡儿积。检索出的行的数目将是第一个表中的行数乘 以第二个表中的行数。
可以看出,笛卡尔积返回的结果行数因为没有进行过滤,数量将会增加很多,而且很多信息并不是我们想要的。因此不要忘了WHERE子句 应该保证所有联结都有WHERE子句,否 则MySQL将返回比想要的数据多得多的数据。同理,应该保 证WHERE子句的正确性。不正确的过滤条件将导致MySQL返回不正确的数据。
为了防止忘记联结条件,通常会这样写:
两种方法都可以,但是第二种更加推荐,可以更好的防止忘记写联结条件。
联结多个表
SQL对一条SELECT语句中可以联结的表的数目没有限制。创建联结 的基本规则也相同。首先列出所有表,然后定义表之间的关系。例如:
**性能考虑:**MySQL在运行时关联指定的每个表以处理联结。 这种处理可能是非常耗费资源的,因此应该仔细,不要联结不必要的表。联结的表越多,性能下降越厉害。
《创建高级联结》
1.使用表的别名
比较简单,举例说明:
2.使用不同类型的联结
(1)自联结
假如你发现某物品(其ID为DTNTR)存在问题,因此想知道生产该物 品的供应商生产的其他物品是否也存在这些问题。此查询要求首先找到 生产ID为DTNTR的物品的供应商,然后找出这个供应商生产的其他物品。 下面是解决此问题的一种方法:
2.自然联结
无论何时对表进行联结,应该至少有一个列出现在不止一个表中(被 联结的列)。标准的联结(前一章中介绍的内部联结)返回所有数据,甚 至相同的列多次出现。自然联结排除多次出现,使每个列只返回一次。
怎样完成这项工作呢?答案是,系统不完成这项工作,由你自己完 成它。自然联结是这样一种联结,其中你只能选择那些唯一的列。这一 般是通过对表使用通配符(SELECT *),对所有其他表的列使用明确的子 集来完成的。下面举一个例子:
3.外部联结
许多联结将一个表中的行与另一个表中的行相关联。但有时候会需 要包含没有关联行的那些行,例如要求输出:对每个客户下了多少订单进行计数,包括那些至今尚未下订单的 客户;
简单的内部联结:
外部联结语法类似。为了检索所有客户,包括那些没有订单的客户, 可如下进行:
两者的区别:
左外联结 Left OUTER JOIN: 以左边的表为标准,找到右边表中相应的对等元素,然后两行联结,如果右边表不包含相应的对等元素,此行对应的右边元素全为NULL。
右外联结RIGHT OUTER JOIN: 则与左外联结完全相反。
外部联结的类型 存在两种基本的外部联结形式:左外部联结 和右外部联结。它们之间的唯一差别是所关联的表的顺序不 同。换句话说,左外部联结可通过颠倒FROM或WHERE子句中表的顺序转换为右外部联结。因此,两种类型的外部联结可互 换使用,而究竟使用哪一种纯粹是根据方便而定。
4.使用带聚集函数的联结
聚集函数用来汇总数据。虽然至今为止聚集函数 的所有例子只是从单个表汇总数据,但这些函数也可以与联结一起使用。为说明这一点,请看一个例子。如果要检索所有客户及每个客户所 下的订单数,下面使用了COUNT()函数的代码可完成此工作:
聚集函数也可以方便地与其他联结一起使用,这里不再赘述其他。
使用联结和联结条件
《组合查询》
1.union
UNION指示MySQL执行两条SELECT语句,并把输出组 合成单个查询结果集。简单一个字“并”。
例:
UNION的使用规则:
<1>.UNION必须由两条或两条以上的SELECT语句组成,语句之间用关 键字UNION分隔(因此,如果组合4条SELECT语句,将要使用3个 UNION关键字) 。
<2>.UNION中的每个查询必须包含相同的列、表达式或聚集函数(不各个列不需要以相同的次序列出)。
<3>.列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以 隐含地转换的类型(例如,不同的数值类型或不同的日期类型)
2.包含或取消重复的行
UNION从查询结果集中自动去除了重复的行(换句话说,它的行为与 单条SELECT语句中使用多个WHERE子句条件一样)。
这是UNION的默认行为,但是如果需要,可以改变它。事实上,如果 想返回所有匹配行,可使用UNION ALL而不是UNION.
3. 对组合查询结果排序
**SELECT语句的输出用ORDER BY子句排序。在用UNION组合查询时,只 能使用一条ORDER BY子句,它必须出现在最后一条SELECT语句之后。**对 于结果集,不存在用一种方式排序一部分,而又用另一种方式排序另一 部分的情况,因此不允许使用多条ORDER BY子句。
例:
优点:使用UNION可极大地简化复杂的WHERE子句。