《SQL基础教程》第06章 多表结合查询


"结合"也就是多个表连接在一起进行查询。这是SQL的重要内容,必须理解 等价结合、非等价结合、外部结合、自身结合4个概念,同时要防止因疏惑造成 "笛卡儿积"的情况。

多个表就有可能存在相同名称的字段,使用时究竟用的是哪个表中的字段, 这就需要在字段的前面加上表的名称,例如STUFF.DEPID,DEPARTMENT.DEPID。 表中不重名的字段可以不附加表名,为了便于理解,人们还是习惯于附加表名。

由于表的名称有可能很长,造成使用不方便,因此,有必要使用表的别名。 表的别名只能在FROM子句里定义,(注意:字段别名是在SELECT子句中定义)。 (例如:from STUFF ta1, DEPARTMENT ta2)

等价结合

表与表之间的条件是等价的,没有主从关系。下例中条件改为:B.DEPID = A.DEPID 结果完全一样。

SQL> select A.DEPID, A.DEPNAME, A.DEPADDR, B.STDID, B.STDNAME
  2  from   DEPARTMENT A, STUFF B
  3  where  A.DEPID = B.DEPID;

DE DEPNAME    DEPADDR                    STDI STDNAME
-- ---------- -------------------------- ---- --------
20 开发       南京                       7360 张妃
30 销售       北京                       7499 关玉
30 销售       北京                       7521 刘蓓
20 开发       南京                       7566 江叁讲
30 销售       北京                       7654 李斯硼
30 销售       北京                       9698 邓笑评
10 会计       上海                       7782 孙荃
20 开发       南京                       7788 周语
10 会计       上海                       7839 鲁素
30 销售       北京                       7844 曹草
20 开发       南京                       7876 诸葛靓
20 开发       南京                       7902 穆归营
10 会计       上海                       7934 花牧岚

已选择13行。

非等价结合

表于表之间是等价之外的关系,同样没有主从关系。

SQL> select A.STDNAME, A.SALARY, B.LVLID, B.MINSALR, B.MAXSALR
  2  from   STUFF A, SALRLEVEL B
  3  where  A.SALARY between B.MINSALR and B.MAXSALR;

STDNAME      SALARY      LVLID    MINSALR    MAXSALR
-------- ---------- ---------- ---------- ----------
刘蓓           2250          2       2001       2500
李斯硼         2250          2       2001       2500
曹草           2500          2       2001       2500
诸葛靓         2100          2       2001       2500
花牧岚         2300          2       2001       2500
关玉           2600          3       2501       3000
江叁讲         2975          3       2501       3000
周语           3000          3       2501       3000
穆归营         3000          3       2501       3000
孙荃           3450          4       3001       3500
邓笑评         3850          5       3501       9999
鲁素           9000          5       3501       9999
张妃           1800          1       1500       2000
已选择13行。

直积结合

不指定任何条件的结合就是直积结合。表中每一项与另一表的每一项逐个组合, 即"笛卡儿积"。千万小心。下面例子中记录数应为13×4=52

SQL> select A.DEPID, A.DEPNAME, A.DEPADDR, B.STDID, B.STDNAME
  2  from   DEPARTMENT A, STUFF B;

DE DEPNAME    DEPADDR                    STDI STDNAME
-- ---------- -------------------------- ---- --------
10 会计       上海                       7360 张妃
20 开发       南京                       7360 张妃
30 销售       北京                       7360 张妃

......   此处省略

10 会计       上海                       7934 花牧岚
20 开发       南京                       7934 花牧岚
30 销售       北京                       7934 花牧岚
40 管理       南京                       7934 花牧岚

已选择52行。

自己结合

自己结合是结合的一种特殊情况,即两个表实际上是同一个表,这时一定 要使用表的别名。注意:两个表中字段名完全相同,因此,字段前的表名一定 不能省略。

SQL> select 部下.STDID, 部下.STDNAME, 部下.LEADER,
  2         上司.STDID, 上司.STDNAME
  3  from   STUFF 部下, STUFF 上司
  4  where  部下.LEADER = 上司.STDID;

STDI STDNAME  LEAD STDI STDNAME
---- -------- ---- ---- --------
7360 张妃     7902 7902 穆归营
7566 江叁讲   7839 7839 鲁素
9698 邓笑评   7839 7839 鲁素
7782 孙荃     7839 7839 鲁素
7788 周语     7566 7566 江叁讲
7876 诸葛靓   7788 7788 周语
7902 穆归营   7566 7566 江叁讲
7934 花牧岚   7782 7782 孙荃

已选择8行。

外部结合

★★★

表与表之间有主从关系,即1对多的关系。下例中的条件部分也可以 写成:where B.DEPID(+) = A.DEPID。但写成where A.DEPID(+) = B.DEPID, 则意义完全不一样了。

本章是SQL的重点,而本小节又是本章的重点,必须反复联系,彻底理解 方能通过。否则,容易与分组、子查询等概念混淆。

SQL> select A.DEPID, A.DEPNAME, A.DEPADDR, B.STDID, B.STDNAME
  2  from   DEPARTMENT A, STUFF B
  3  where  A.DEPID = B.DEPID(+);

DE DEPNAME    DEPADDR                    STDI STDNAME
-- ---------- -------------------------- ---- --------
10 会计       上海                       7782 孙荃
10 会计       上海                       7839 鲁素
10 会计       上海                       7934 花牧岚
20 开发       南京                       7360 张妃
20 开发       南京                       7876 诸葛靓
20 开发       南京                       7788 周语
20 开发       南京                       7566 江叁讲
20 开发       南京                       7902 穆归营
30 销售       北京                       7499 关玉
30 销售       北京                       9698 邓笑评
30 销售       北京                       7654 李斯硼
30 销售       北京                       7844 曹草
30 销售       北京                       7521 刘蓓
40 管理       南京

已选择14行。

3个以上表的结合

SQL> select A.DEPID, B.STDNAME, B.SALARY, C.LVLID
  2  from   DEPARTMENT A, STUFF B, SALRLEVEL C
  3  where  A.DEPID = B.DEPID and 
  4         B.SALARY between C.MINSALR and C.MAXSALR;

DE STDNAME      SALARY      LVLID
-- -------- ---------- ----------
30 刘蓓           2250          2
30 李斯硼         2250          2
30 曹草           2500          2
20 诸葛靓         2100          2
10 花牧岚         2300          2
30 关玉           2600          3
20 江叁讲         2975          3
20 周语           3000          3
20 穆归营         3000          3
10 孙荃           3450          4
30 邓笑评         3850          5
10 鲁素           9000          5
20 张妃           1800          1

已选择13行。