随便玩玩之PostgreSQL(第三章)表连接查询

随便玩玩之PostgreSQL(第三章)表连接查询


随便玩玩之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为表和字段取别名

 

posted @ 2017-11-12 17:36  冲浪的奶糖  阅读(1393)  评论(0编辑  收藏  举报