1. 内连接查询
内连接 ( INNER JOIN )是使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行,组合成新的记录。也就是说,在内连接查询中,只有满足条件的记录才能出现在结果关系中。
【例】在 fruits 表和 suppliers 表之间使用内连接查询。
查询之前,查看两个表的结构:
mysql> DESC fruits; +---------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +---------+--------------+------+-----+---------+-------+ | f_id | char(10) | NO | PRI | NULL | | | s_id | int(11) | NO | | NULL | | | f_name | char(255) | NO | | NULL | | | f_price | decimal(8,2) | NO | | NULL | | +---------+--------------+------+-----+---------+-------+
mysql> DESC suppliers; +--------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------+----------+------+-----+---------+----------------+ | s_id | int(11) | NO | PRI | NULL | auto_increment | | s_name | char(50) | NO | | NULL | | | s_city | char(50) | YES | | NULL | | | s_zip | char(10) | YES | | NULL | | | s_call | char(50) | NO | | NULL | | +--------+----------+------+-----+---------+----------------+
fruits 表和 suppliers 表中都有相同数据类型的字段 s_id,两个表可以通过 s_id 字段建立联系。接下来从 fruits 表中查询 f_name、f_price 字段,从 suppliers 表中查询 s_id、s_name,SQL 语句如下:
mysql> SELECT fruits.s_id, s_name,f_name,f_price -> FROM fruits, suppliers -> WHERE fruits.s_id = suppliers.s_id; +------+-----------------+------------+---------+ | s_id | s_name | f_name | f_price | +------+-----------------+------------+---------+ | 101 | FastFruit Inc. | apple | 5.20 | | 103 | ACME | apricot | 2.20 | | 101 | FastFruit Inc. | blackberry | 10.20 | | 104 | FNK Inc. | berry | 7.60 | | 107 | DK Inc. | xxxx | 3.60 | | 102 | LT Supplies | orange | 11.20 | | 105 | Good Set | melon | 8.20 | | 101 | FastFruit Inc. | cherry | 3.20 | | 104 | FNK Inc. | lemon | 6.40 | | 106 | Just Eat Ours | mango | 15.60 | | 105 | Good Set | xbabay | 2.60 | | 105 | Good Set | xxtt | 11.60 | | 103 | ACME | coconut | 9.20 | | 102 | LT Supplies | blanana | 10.30 | | 102 | LT Supplies | grape | 5.30 | | 107 | DK Inc. | xbababa | 3.60 | +------+-----------------+------------+---------+
【例】在 fruits 表和 suppliers 表之间,使用 INNER JOIN 语法进行内连接查询。SQL语句如下:
mysql> SELECT fruits.s_id, s_name,f_name,f_price -> FROM fruits INNER JOIN suppliers -> ON fruits.s_id = suppliers.s_id; +------+-----------------+------------+---------+ | s_id | s_name | f_name | f_price | +------+-----------------+------------+---------+ | 101 | FastFruit Inc. | apple | 5.20 | | 103 | ACME | apricot | 2.20 | | 101 | FastFruit Inc. | blackberry | 10.20 | | 104 | FNK Inc. | berry | 7.60 | | 107 | DK Inc. | xxxx | 3.60 | | 102 | LT Supplies | orange | 11.20 | | 105 | Good Set | melon | 8.20 | | 101 | FastFruit Inc. | cherry | 3.20 | | 104 | FNK Inc. | lemon | 6.40 | | 106 | Just Eat Ours | mango | 15.60 | | 105 | Good Set | xbabay | 2.60 | | 105 | Good Set | xxtt | 11.60 | | 103 | ACME | coconut | 9.20 | | 102 | LT Supplies | blanana | 10.30 | | 102 | LT Supplies | grape | 5.30 | | 107 | DK Inc. | xbababa | 3.60 | +------+-----------------+------------+---------+
使用 WHERE 子句定义连接条件比较简单明了,但在某些时候会影响查询的性能,而 INNER JOIN 语法是 ANSI SQL 的标准规范,使用 INNER JOIN 连接语法能够确保不会忘记连接条件。
如果在一个连接查询中,涉及的两个表都是同一个表,这种查询称为自连接查询。自连接是一种特殊的内连接,它是指相互连接的表在物理上为同一张表,但可以在逻辑上分为两张表。
【例】查询 f_i='a1' l的水果供应商提供的水果种类,SQL语句如下:
mysql> SELECT f1.f_id, f1.f_name -> FROM fruits AS f1,fruits AS f2 -> WHERE f1.s_id= f2.s_id AND f2.f_id='a1'; +------+------------+ | f_id | f_name | +------+------------+ | a1 | apple | | b1 | blackberry | | c0 | cherry | +------+------------+此处查询的两个表是同一个表,为了防止产生二义性,对表使用了别名,fruits 表第1次出现的别名为 f1,第2次出现的别名为 f2。使用 SELECT 语句返回列时明确指出运回以 f1 为前缀的列的全名,WHERE 连接两个表,并按照第 2 个表的 f_id 对数据进行过滤,返回所需数据。
2. 外连接查询
连接查询将查询多个表中相关联的行,内连接时,只返回符合查询条件和连接条件的行。如果要返回没有关联的行中数据,即返回的查询结果集合中不仅包含符合连接条件的行,而且还包括左表 (左外连接或左连接)、右表(右外连接或右连接)或两个边接表(全外连接)中的所有数据行,这时就要用到外连接查询。
外连接分为左外连接和右外连接。
a. LEFT JOIN(左连接): 返回左表中的所有记录和右表中与连接字段相等的记录。b. RIGHT JOIN(右连接): 返回右表中的所有记录和左表中与连接字段相等的记录。
a. LEFT JOIN 左连接
连接的结果包括 LEFT OUTER 子句中指定的左表的所有行,而不仅是连接列所匹配的行。如果左表的某行在右表中没有匹能行,则在相关联的结果行中 ,右表的所有选择列均为空值。mysql> desc orders; +--------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------+----------+------+-----+---------+----------------+ | o_num | int(11) | NO | PRI | NULL | auto_increment | | o_date | datetime | NO | | NULL | | | c_id | int(11) | NO | | NULL | | +--------+----------+------+-----+---------+----------------+
mysql> desc customers; +-----------+-----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-----------+-----------+------+-----+---------+----------------+ | c_id | int(11) | NO | PRI | NULL | auto_increment | | c_name | char(50) | NO | | NULL | | | c_address | char(50) | YES | | NULL | | | c_city | char(50) | YES | | NULL | | | c_zip | char(10) | YES | | NULL | | | c_contact | char(50) | YES | | NULL | | | c_email | char(255) | YES | | NULL | | +-----------+-----------+------+-----+---------+----------------+
【例】在 customers 表和 orders 表中,查询所有客户,包括没有订单的客户,SQL语句如下:
mysql> select customers.c_id, orders.o_num -> FROM customers LEFT OUTER JOIN orders -> ON customers.c_id=orders.c_id; +-------+-------+ | c_id | o_num | +-------+-------+ | 10001 | 30001 | | 10003 | 30002 | | 10004 | 30003 | | 10001 | 30005 | | 10002 | NULL | +-------+-------+
b. RIGHT JOIN 右连接
右连接是左连接的反向连接,将返回右表中的所有行。如果右表的某行在左表中没有匹配行,左表将返回空值。
【例】在 customers 表和 orders 表中,查询所有订单,包括没有客户的订单,SQL语句如下:
mysql> select customers.c_id, orders.o_num -> FROM customers RIGHT OUTER JOIN orders -> ON customers.c_id=orders.c_id; +-------+-------+ | c_id | o_num | +-------+-------+ | 10001 | 30001 | | 10003 | 30002 | | 10004 | 30003 | | NULL | 30004 | | 10001 | 30005 | +-------+-------+
3. 复合条件连接查询
复合条件连接查询是在连接查询的过程中,通过添加过滤条件,限制查询的结果,使查询的结果更加准确。
【例】在 customers 表和 orders 表中,使用 INNER JOIN 语法查询 customers 表中 ID 为 10001 的客户的订单信息。SQL 语句如下:
mysql> select customers.c_id, orders.o_num -> FROM customers INNER JOIN orders -> ON customers.c_id=orders.c_id AND customers.c_id=10001; +-------+-------+ | c_id | o_num | +-------+-------+ | 10001 | 30001 | | 10001 | 30005 | +-------+-------+
使用连接查询时,可以对查询结果进行排序。
【例】在 fruits 表和 suppliers 表之间,使用 INNER JOIN 语法进行内连接查询,并对查询结果排序。SQL 语句如下;
mysql> select suppliers.s_id,s_name,f_name,f_price -> from fruits INNER JOIN suppliers -> ON fruits.s_id = suppliers.s_id -> order by fruits.s_id; +------+-----------------+------------+---------+ | s_id | s_name | f_name | f_price | +------+-----------------+------------+---------+ | 101 | FastFruit Inc. | apple | 5.20 | | 101 | FastFruit Inc. | blackberry | 10.20 | | 101 | FastFruit Inc. | cherry | 3.20 | | 102 | LT Supplies | orange | 11.20 | | 102 | LT Supplies | blanana | 10.30 | | 102 | LT Supplies | grape | 5.30 | | 103 | ACME | apricot | 2.20 | | 103 | ACME | coconut | 9.20 | | 104 | FNK Inc. | berry | 7.60 | | 104 | FNK Inc. | lemon | 6.40 | | 105 | Good Set | melon | 8.20 | | 105 | Good Set | xbabay | 2.60 | | 105 | Good Set | xxtt | 11.60 | | 106 | Just Eat Ours | mango | 15.60 | | 107 | DK Inc. | xxxx | 3.60 | | 107 | DK Inc. | xbababa | 3.60 | +------+-----------------+------------+---------+