php 内连接和外连接,postgreSQL中的内连接和外连接实现操作

测试数据:

city表:

create table city(id int,name text);

insert into city values(0,'北京'),(1,'西安'),(2,'天津'),(3,'上海'),(4,'哈尔滨'),(5,'西藏')

person表:

create table person(id int,lastname char(20));

insert into person values(0,'Tom'),(2,'Lily'),(3,'Mary'),(5,'Coco');

select * from city;

f6f4f83b69858b6f1784cec2cb096705.png

select * from person;

c47c1ceb1e3a595a0becd3a849a2303c.png

一:内连接:

1.inner join

inner join(等值连接) 只返回两个表中联结字段相等的行

sql语句:

select * from city inner join person on city.id = person.id;

也可以写成:

select * from city join person on city.id = person.id;

结果如下:

ebb89da8bfad91a6e60e14938800d6b4.png

从结果可以看出,表格中显示出了city.id=person.id的记录,它显示出了符合这个条件的记录。

二:外连接:

1.full outer join

full outer join(全外连接)返回参与连接的两个数据集合中的全部数据

sql语句:

select * from city full outer join person on city.id = person.id;

也可以写成:

select * from city full join person on city.id = person.id;

结果如下:

09567696c7f1c3b75dc533accb220796.png

从结果可以看出,全外连接得到了city和person表中的全部数据

2.left outer join

left outer join(左连接) 返回包括左表中的所有记录和右表中连接字段相等的记录

sql语句:

select * from city left outer join person on city.id = person.id;

也可以写成:

select * from city left join person on city.id = person.id;

结果如下:

9b69dde3a4f41385b3192a454be30d15.png

从结果可以看出,左外连接和全外连接的结果一模一样?

我们在给person中添加一行数据:

insert into person values(9,'Kiki');

d2fb3e97bb1fad334c9db3e3ec687ea5.png

在重新执行:

select * from city full join person on city.id = person.id;

结果如下:

666b9c39c505c9864c881442ad167f79.png

select * from city left join person on city.id = person.id;

结果如下:

3f949bc7da790280f6ad8d37c033a811.png

两个结果对照着看,left join显示出了city中的所有记录和person连接字段相等的记录

3.right outer join

right outer join(右连接) 返回包括右表中的所有记录和左表中连接字段相等的记录

sql语句:

select * from city right outer join person on city.id = person.id;

也可以写成

select * from city right join person on city.id = person.id;

结果如下:

258a95882cd21d0758bafb39a0ae966e.png

从结果可以看出,person中的记录被全部显示出来,而city中的显示的数据是根据连接字段相等的记录

补充:PostgreSQL表连接:内连接,外连接,自连接,交叉连接

搜了搜,基本上都是写内连接、外连接、交叉连接这三种类型,但我发现PostgreSQL还有自连接。不妨一并写来做个记录。

先说概念:

内连接,就是两个表逐行匹配,匹配上的内容都显示,没有匹配的都不显示。

外连接有三种,左外连接,右外连接,全外连接。

左外连接是以左表为基础,左表内容全部显示,右表有匹配到左表的则显示,否则不显示。

右外连接是以右表为基础,右表内容全部显示,左表有匹配到右表的则显示,否则不显示。

全外连接是以两表为基础,显示三部分内容,一部分是内连接的内容,即两表匹配的内容,一部分是左表有而右表无的,一部分是左表无右表有的。

自连接是逐行,用当前这行数据和这个表中其他行进行匹配。

交叉连接最省事,笛卡尔积,左表m行右表n行,则结果是m*n行。

下面展示具体例子来帮助理解。

下面是两个表的内容。

mydb=# select * from weather;

city | temp_lo | temp_hi | prcp | date

---------------+---------+---------+------+------------

San Francisco | 46 | 50 | 0.25 | 1994-11-27

San Francisco | 43 | 57 | 0 | 1994-11-29

Hayward | 37 | 54 | | 1994-11-29

(3 行记录)

mydb=# select * from cities;

name | location

---------------+-----------

San Francisco | (-194,53)

London | (0,51)

(2 行记录)

内连接有两种写法:

mydb=# SELECT *

mydb-# FROM weather, cities

mydb-# WHERE city = name;

city | temp_lo | temp_hi | prcp | date | name | location

---------------+---------+---------+------+------------+---------------+-----------

San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)

San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)

(2 行记录)

mydb=# SELECT *

mydb-# FROM weather INNER JOIN cities ON (weather.city = cities.name);

city | temp_lo | temp_hi | prcp | date | name | location

---------------+---------+---------+------+------------+---------------+-----------

San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)

San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)

(2 行记录)

外连接有三种:左外连接,右外连接,全外连接。

mydb=# SELECT *

mydb-# FROM weather LEFT OUTER JOIN cities ON (weather.city = cities.name);

city | temp_lo | temp_hi | prcp | date | name | location

---------------+---------+---------+------+------------+---------------+-----------

San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)

San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)

Hayward | 37 | 54 | | 1994-11-29 | |

(3 行记录)

mydb=# select * from weather right outer join cities on(weather.city=cities.name);

city | temp_lo | temp_hi | prcp | date | name | location

---------------+---------+---------+------+------------+---------------+-----------

San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)

San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)

| | | | | London | (0,51)

(3 行记录)

mydb=# select * from weather full outer join cities on(weather.city=cities.name);

city | temp_lo | temp_hi | prcp | date | name | location

---------------+---------+---------+------+------------+---------------+-----------

San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)

San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)

Hayward | 37 | 54 | | 1994-11-29 | |

| | | | | London | (0,51)

(4 行记录)

表交叉连接:

mydb=# SELECT *

mydb-# FROM weather, cities;

city | temp_lo | temp_hi | prcp | date | name | location

---------------+---------+---------+------+------------+---------------+-----------

San Francisco | 46 | 50 | 0.25 | 1994-11-27 | San Francisco | (-194,53)

San Francisco | 46 | 50 | 0.25 | 1994-11-27 | London | (0,51)

San Francisco | 43 | 57 | 0 | 1994-11-29 | San Francisco | (-194,53)

San Francisco | 43 | 57 | 0 | 1994-11-29 | London | (0,51)

Hayward | 37 | 54 | | 1994-11-29 | San Francisco | (-194,53)

Hayward | 37 | 54 | | 1994-11-29 | London | (0,51)

(6 行记录)

表自连接:

mydb=# SELECT W1.city, W1.temp_lo AS low, W1.temp_hi AS high,

mydb-# W2.city, W2.temp_lo AS low, W2.temp_hi AS high

mydb-# FROM weather W1, weather W2

mydb-# WHERE W1.temp_lo < W2.temp_lo

mydb-# AND W1.temp_hi > W2.temp_hi;

city | low | high | city | low | high

---------------+-----+------+---------------+-----+------

San Francisco | 43 | 57 | San Francisco | 46 | 50

Hayward | 37 | 54 | San Francisco | 46 | 50

(2 行记录)

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。如有错误或未考虑完全的地方,望不吝赐教。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值