tashi-net


随便玩玩之PostgreSQL

 未经授权不得转载

第三章 表连接查询

连接查询是关系数据库中最主要的查询,主要包括内连接、外连接和自连接等。

 3.1 准备数据

先创建学生基本信息表。

1 CREATE TABLE jbxx(
2     id    int,
3     xm    varchar(20),
4     xb    varchar(1),
5     sfzh  varchar(18),
6     bj    varchar(2),
7     zz    varchar(50),
8     lxdh  varchar(11)
9 );

再插入一些数据。

1 INSERT INTO jbxx(id, xm, xb, sfzh, bj, zz, lxdh)   VALUES (1,\'李四\',\'\',\'11010119990101103X\',\'二班\',\'北京市东城区\',\'13900100001\');
2 INSERT INTO jbxx(id, xm, xb, sfzh, bj, zz, lxdh)   VALUES (3,\'张三\',\'\',\'120101199901014419\',\'二班\',\'天津市和平区\',\'13900100002\');
3 INSERT INTO jbxx(id, xm, xb, sfzh, bj, zz, lxdh)   VALUES (5,\'赵六\',\'\',\'110101199906104171\',\'三班\',\'北京市东城区\',\'13900100003\');
4 INSERT INTO jbxx(id, xm, xb, sfzh, bj, zz, lxdh)   VALUES (7,\'刘一\',\'\',\'110102199910178874\',\'一班\',\'北京市西城区\',\'13900100004\');
5 INSERT INTO jbxx(id, xm, xb, sfzh, bj, zz, lxdh)   VALUES (8,\'吴九\',\'\',\'110224199807080450\',\'一班\',\'北京市大兴县\',\'13900100005\');
6 INSERT INTO jbxx(id, xm, xb, sfzh, bj, zz, lxdh)   VALUES (9,\'郑十\',\'\',\'120221199909120292\',\'一班\',\'天津市宁河县\',\'13900100006\');
7 INSERT INTO jbxx(id, xm, xb, sfzh, bj, zz, lxdh)   VALUES (2,\'王五\',\'\',\'130101199901081445\',\'二班\',\'河北省石家庄市\',\'13900100007\');
8 INSERT INTO jbxx(id, xm, xb, sfzh, bj, zz, lxdh)   VALUES (4,\'孙七\',\'\',\'110101199905152083\',\'三班\',\'北京市东城区\',\'13900100008\');
9 INSERT INTO jbxx(id, xm, xb, sfzh, bj, zz, lxdh)   VALUES (6,\'周八\',\'\',\'110102199906106763\',\'三班\',\'北京市西城区\',\'13900100009\');

查看数据。

SELECT * FROM jbxx;

结果如图。

3.2内连接查询

内连接使用inner join操作符,内连接查询的查询结果集中仅包含满足条件的行。

内连接又称为相等连接或自然连接,根据连接的表内共有的列匹配表中的行。

如:查询其中考试语文成绩大于70的学生的基本信息。

1 SELECT cj.kc,
2        cj.xm,
3        cj.yw,
4        jbxx.* 
5     FROM cj,jbxx 
6     WHERE jbxx.xm=cj.xm 
7         AND kc =\'期中考试\' 
8         AND yw >70;

结果如图:

如果不限定其中考试和语文成绩,则会列出成绩表(cj)所有信息和基本信息表(jbxx)所有信息。

SELECT *  FROM cj,jbxx  WHERE jbxx.xm=cj.xm;

其中cj表有每个人有两个姓名,jbxx表每个人只有一个姓名,jbxx的表内信息出现两次。这不是出错,关系数据库本来就是这样的机制。

如果不指定连接字段(限制条件),则会得到18X9=162条记录,有很多错误数据(冗余),这叫笛卡尔积。实际应用中,笛卡尔积没有什么实际用处。

内连接加不加操作符都一样,前提是要指定连接字段。

1 SELECT *  
2    FROM cj inner join jbxx 
3    ON jbxx.xm=cj.xm
4    WHERE  kc =\'期中考试\' AND yw >70;

结果如图。

ON jbxx.xm=cj.xm等同于WHERE jbxx.xm=cj.xm 。加INNER JOIN的叫显式连接,不加的角隐式连接。

 3.3外连接

外连接包括左外连接(LEFT OUTER JOIN)、右外连接(RIGHT OUTER JOIN)和全外连接(FULL OUTER JOIN)。

三者的共同点是都返回符合连接条件和查询条件(即:内连接)的数据行。不同点如下:
左外连接还返回左表中不符合连接条件单符合查询条件的数据行。
右外连接还返回右表中不符合连接条件单符合查询条件的数据行。
全外连接还返回左表中不符合连接条件单符合查询条件的数据行,并且还返回右表中不符合连接条件单符合查询条件的数据行。全外连接实际是上左外连接和右外连接的数学合集(去掉重复),即“全外=左外 UNION 右外”。

左表就是在“(LEFT OUTER JOIN)”关键字左边的表。右表当然就是右边的了。在三种类型的外连接中,OUTER 关键字是可省略的。

3.3.1 左外连接。

如:查询成绩表中所有人的基本信息。

SELECT * 
    FROM cj LEFT OUTER JOIN jbxx 
        ON cj.xm=jbxx.xm;

结果如图。

3.3.2右外连接

如:查询基本信息中所有人的成绩。

SELECT * 
    FROM cj RIGHT OUTER JOIN jbxx 
        ON cj.xm=jbxx.xm;

结果如图。

3.3.3全连接

如:查询cj表和jbxx表中,不管左边有或右边有,全部列出来。

SELECT * 
    FROM cj FULL OUTER JOIN jbxx 
        ON cj.xm=jbxx.xm;

结果如图。

注:这几个连接查询的结果数据都一样,因为基本信息表的学生在成绩表中都有。稍后将从新整理这一章内容。

3.3.4自连接

自连接是一种特殊的连接,连接的表同源。简单地说就是一张表起两个名字,连接这两张表再查询。

如:

SELECT a.xm,b.xm
FROM jbxx a inner join jbxx b
ON a.xm=b.xm

结果如图。

 

3.4合并查询结果。

合并查询使用UNION关键字,可以将多条SELECT语句的结果合并成一个结果。合并时,两个表的列数和数据类型必须相同。

合并时可以在UNION后加ALL关键字,也可以不加。不加的结果为删除查询结果的重复行,加ALL后的结果为列出所有查询的结果,包括重复行。

如:查询期中考试成绩和一班学生的成绩。

SELECT * FROM CJ WHERE kc=\'期中考试\'
UNION
SELECT * FROM CJ WHERE bj=\'一班\';

结果如图。

结果包括期中考试的成绩和一班的期中期末考试成绩。结果已经去掉一班的期中成绩和期中考试中一般的成绩,重复的只保留一个。加上ALL操作符可以保留重复数据。

SELECT * FROM CJ WHERE kc=\'期中考试\'
UNION ALL
SELECT * FROM CJ WHERE bj=\'一班\';

结果如图。

另外的例子。查询成绩表和基本信息表中出现的名字总和。

SELECT id,bj,xm FROM cj
UNION ALL
SELECT id,bj,xm FROM jbxx;

结果如图。

结果没有去掉重复,为18+9=27行记录。

3.5为表和字段取别名

 

分类:

技术点:

相关文章: