0
点赞
收藏
分享

微信扫一扫

数据库基础之联结表

sullay 2022-04-27 阅读 87

目录

1、联结

1.1 关系表

1.2、为什么使用联结

2、创建联结

2.1、WHERE子句的重要性

2.2、内联结

2.3、联结多个表


1、联结

SQL最强大的功能之一就是能在数据查询的执行中联结(join)表。联结是利用SQL的SELECT能执行的最重要的操作。

1.1 关系表

理解关系表,最好是来看个例子。

有一个包含产品目录的数据库表,其中每类物品占一行。对于每一种物品,要存储的信息包括产品描述、价格,以及生产该产品的供应商。

现在有同一供应商生产的多种物品,那么在何处存储供应商名、地址、联系方法等供应商信息呢?将这些数据与产品信息分开存储的理由是:

  1. 同一供应商生产的每个产品,其供应商信息都是相同的,对每个产品重复此信息既浪费时间又浪费存储空间;
  2.  如果供应商信息发生变化,例如供应商迁址或电话号码变动,只需修改一次即可;
  3.  如果有重复数据(即每种产品都存储供应商信息),则很难保证每次输入该数据的方式都相同。不一致的数据在报表中就很难利用。

关键是,相同的数据出现多次出现决不是一件好事,这是关系数据库设计的基础。关系表的设计就是要把信息分解成多个表,一类数据一个表。各表通过某些共同的值互相关联(所以才叫关系数据库)。
在这个例子中可建立两个表:一个存储供应商信息,另一个存储产品信息。Vendors表包含所有供应商信息,每个供应商占一行,具有唯一的标识。此标识称为主键(primary key),可以是供应商ID或任何其他唯一值。

Products表只存储产品信息,除了存储供应商ID(Vendors表的主键)外,它不存储其他有关供应商的信息。Vendors表的主键将Vendors表与Products表关联,利用供应商ID能从Vendors表中找出相应供应商的详细信息。

这样做的好处是:

  1. 供应商信息不重复,不会浪费时间和空间;
  2.  如果供应商信息变动,可以只更新Vendors表中的单个记录,相关表中的数据不用改动;
  3.  由于数据不重复,数据显然是一致的,使得处理数据和生成报表更简单。

总之,关系数据可以有效地存储,方便地处理。因此,关系数据库的可伸缩性远比非关系数据库要好。

1.2、为什么使用联结

如前所述,将数据分解为多个表能更有效地存储,更方便地处理,并且可伸缩性更好。但这些好处是有代价的。 如果数据存储在多个表中,怎样用一条SELECT语句就检索出数据呢?

答案是使用联结。简单说,联结是一种机制,用来在一条SELECT语句中关联表,因此称为联结。使用特殊的语法,可以联结多个表返回一组输出,联结在运行时关联表中正确的行。

2、创建联结

创建联结非常简单,指定要联结的所有表以及关联它们的方式即可。请看下面的例子:

输入:

SELECT vend_name, prod_name, prod_price FROM Vendors, Products 
WHERE Vendors.vend_id = Products.vend_id;

输出:

我们来看这段代码。SELECT语句与前面所有语句一样指定要检索的列。这里最大的差别是所指定的两列(prod_name和prod_price)在一个表中,而第三列(vend_name)在另一个表中。

现在来看FROM子句。与以前的SELECT语句不一样,这条语句的FROM子句列出了两个表:Vendors和Products。它们就是这条SELECT语句联结的两个表的名字。这两个表用WHERE子句正确地联结,WHERE子句指示DBMS将Vendors表中的vend_id与Products表中的vend_id匹配起来。 可以看到,要匹配的两列指定为Vendors.vend_id和Products.vend_id。这里需要这种完全限定列名,如果只给出vend_id,DBMS就不知道指的是哪一个(每个表中有一个)。从前面的输出可以看到,一条SELECT语句返回了两个不同表中的数据。

2.1、WHERE子句的重要性

使用WHERE子句建立联结关系似乎有点奇怪,但实际上是有个很充分的理由的。要记住,在一条SELECT语句中联结几个表时,相应的关系是在运行中构造的。在数据库表的定义中没有指示DBMS如何对表进行联结的内容。你必须自己做这件事情。在联结两个表时,实际要做的是将第一个表中的每一行与第二个表中的每一行配对。WHERE子句作为过滤条件,只包含那些匹配给定条件(这里是联结条件)的行。没有WHERE子句,第一个表中的每一行将与第二个表中的每一行配对,而不管它们逻辑上是否能配在一起。

请看下面的SELECT语句及其输出:

输入:

SELECT vend_name, prod_name, prod_price FROM Vendors, Products;

这句返回的就是笛卡尔积。不列举结果了,数据太多了。

2.2、内联结

目前为止使用的联结称为等值联结(equijoin),它基于两个表之间的相等测试。这种联结也称为内联结(inner join)。其实,可以对这种联结使用稍微不同的语法,明确指定联结的类型。下面的SELECT语句返回与前面例子完全相同的数据:

输入:

SELECT vend_name, prod_name, prod_price FROM Vendors 
INNER JOIN Products  ON Vendors.vend_id = Products.vend_id; 

语句中的SELECT与前面的SELECT语句相同,但FROM子句不同。这里,两个表之间的关系是以INNER JOIN指定的部分FROM子句。在使用这种语法时,联结条件用特定的ON子句而不是WHERE子句给出。传递给ON的实际条件与传递给WHERE的相同。

2.3、联结多个表

        SQL不限制一条SELECT语句中可以联结的表的数目。创建联结的基本规则也相同。首先列出所有表,然后定义表之间的关系。例如:

输入:

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; 

输出:

这个例子显示订单20007中的物品。订单物品存储在OrderItems表中。每个产品按其产品ID存储,它引用Products表中的产品。这些产品通过供应商ID联结到Vendors表中相应的供应商,供应商ID存储在每个产品的记录中。这里的FROM子句列出三个表,WHERE子句定义这两个联结条件,而第三个联结条件用来过滤出订单20007中的物品。

子查询下的SELECT语句返回订购产品RGAN01的顾客列表: 

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操作的最有效方法,下面是使用联结的相同查询:

SELECT cust_name, cust_contact FROM Customers, Orders, OrderItems 
WHERE Customers.cust_id = Orders.cust_id  
AND OrderItems.order_num = Orders.order_num  AND prod_id = 'RGAN01'; 

这个查询中的返回数据需要使用3个表。但在这里,我们没有在嵌套子查询中使用它们,而是使用了两个联结来连接表。这里有三个WHERE子句条件。前两个关联联结中的表,后一个过滤产品RGAN01的数据。

举报

相关推荐

0 条评论