sql中的连接查询有inner join(内连接)、left join(左连接)、right join(右连接)、full join(全连接)四种方式,它们之间其实并没有太大区别,仅仅是查询出来的结果有所不同。
例如我们有两张表:
users表
| id | name | age |
|---|---|---|
| 1 | Joe.Ye | 25 |
| 2 | Test | 28 |
| 3 | Xiong | 24 |
orders表
| id | order_no | user_id |
|---|---|---|
| 1 | 100001 | 3 |
| 2 | 100002 | 3 |
| 3 | 100003 | 1 |
| 4 | 100004 | 1 |
| 5 | 100005 | 10 |
orders表通过外键user_id和users表进行关联。
inner join(内连接)
在两张表进行连接查询时,只保留两张表中完全匹配的结果集。使用inner join对两张表进行连接查询,sql如下:
SELECT u.name, u.age, o.order_no
FROM users u
INNER JOIN orders o
ON u.id=o.user_id and 1=1 --用and连接多个条件
ORDER BY u.name
查询结果集:
| name | age | order_no |
|---|---|---|
| Joe.Ye | 25 | 100003 |
| Joe.Ye | 25 | 100004 |
| Xiong | 24 | 100001 |
| Xiong | 24 | 100002 |
此种连接方式orders表中user_id字段在users表中找不到匹配的,则不会列出来。
注意:单纯的select * from a,b是笛卡尔乘积。比如a表有5条数据,b表有3条数据,那么最后的结果有5*3=15条数据。
但是如果对两个表进行关联:select * from a,b where a.id = b.id意思就变了,此时就等价于:
select * from a inner join b on a.id = b.id,即就是内连接。
但是这种写法并不符合规范,可能只对某些数据库管用,如Sql Server。推荐最好不要这样写。最好写成inner join的写法。
left join(左连接)
在两张表进行连接查询时,会返回左表所有的行,即使在右表中没有匹配的记录。我们使用left join对两张表进行连接查询,sql如下:
SELECT u.name, u.age, o.order_no
FROM users u
LEFT JOIN orders o
ON u.id=o.user_id
ORDER BY u.name
查询结果集:
| name | age | order_no |
|---|---|---|
| Joe.Ye | 25 | 100003 |
| Joe.Ye | 25 | 100004 |
| Test | 28 | |
| Xiong | 24 | 100001 |
| Xiong | 24 | 100002 |
可以看到,左表(users表)中name为Test的行的id字段在右表(orders表)中没有匹配,但查询结果仍然保留该行。
right join(左连接)
在两张表进行连接查询时,会返回右表所有的行,即使在左表中没有匹配的记录。我们使用right join对两张表进行连接查询,sql如下:
SELECT u.name, u.age, o.order_no
FROM users u
RIGHT JOIN orders o
ON u.id=o.user_id
ORDER BY u.name
查询结果集:
| name | age | order_no |
|---|---|---|
| Joe.Ye | 25 | 100003 |
| Joe.Ye | 25 | 100004 |
| Xiong | 24 | 100001 |
| Xiong | 24 | 100002 |
| 100005 |
orders表中最后一条记录user_id字段值为10,在左表中没有记录与之匹配,但依然保留。
full join(左连接)
在两张表进行连接查询时,返回左表和右表中所有没有匹配的行。我们使用full join对两张表进行连接查询,sql如下:
SELECT u.name, u.age, o.order_no
FROM users u
FULL JOIN orders o
ON u.id=o.user_id
ORDER BY u.name
查询结果集:
| name | age | order_no |
|---|---|---|
| Joe.Ye | 25 | 100003 |
| Joe.Ye | 25 | 100004 |
| Test | 28 | |
| Xiong | 24 | 100001 |
| Xiong | 24 | 100002 |
| 100005 |
查询结果是left join和right join的并集。