029、SQL语句之表连接

从多个表中查询数据

  • 有些查询需要来自多个表的数据

  • 可以使用join操作来合并来自不同表的数据

  • 要联接表,这些表中的某些列之间应当存在逻辑关系

  • 最佳实现:使用表明别名

  • 示例

mysql> select * from a;
+------+------+
| id   | name |
+------+------+
|    1 | AA   |
|    2 | BB   |
|    3 | AC   |
+------+------+
3 rows in set (0.01 sec)

mysql> select * from b;
+------+------+
| id   | name |
+------+------+
|    1 | BA   |
|    2 | BB   |
|    3 | BC   |
+------+------+
3 rows in set (0.02 sec)

mysql> select * from c;
+------+------+
| id   | name |
+------+------+
|    1 | CA   |
|    2 | CB   |
|    4 | CC   |
+------+------+
3 rows in set (0.01 sec)

mysql> select * from d;
+------+------+
| id   | name |
+------+------+
|    1 | DA   |
|    2 | DB   |
| NULL | DC   |
|    5 | NULL |
+------+------+
4 rows in set (0.00 sec)

笛卡尔积

  • 使用join关键字,但是没有join条件

mysql> select a.name,b.name from a a join b b ;
±-----±-----+
| name | name |
±-----±-----+
| AA | BC |
| AA | BB |
| AA | BA |
| BB | BC |
| BB | BB |
| BB | BA |
| AC | BC |
| AC | BB |
| AC | BA |
±-----±-----+
9 rows in set (0.09 sec)

inner join(内连接)

mysql> select a.name,b.name from a a join b b on a.id=b.id;
+------+------+
| name | name |
+------+------+
| AA   | BA   |
| BB   | BB   |
| AC   | BC   |
+------+------+
3 rows in set (0.05 sec)

mysql> select a.name,c.name from a a join c c on a.id=c.id;
+------+------+
| name | name |
+------+------+
| AA   | CA   |
| BB   | CB   |
+------+------+
2 rows in set (0.01 sec)

mysql> select a.name,d.name from a a join d d on a.id=d.id;
+------+------+
| name | name |
+------+------+
| AA   | DA   |
| BB   | DB   |
+------+------+
2 rows in set (0.00 sec)

外连接

  • 左外连接
mysql> select a.name,c.name from a a left join c c on a.id=c.id;
+------+------+
| name | name |
+------+------+
| AA   | CA   |
| BB   | CB   |
| AC   | NULL |
+------+------+
3 rows in set (0.02 sec)
  • 右外连接
mysql> select a.name,c.name from a a right join c c on a.id=c.id;
+------+------+
| name | name |
+------+------+
| AA   | CA   |
| BB   | CB   |
| NULL | CC   |
+------+------+
3 rows in set (0.00 sec)

外连接和NULL

  • null 在外连接中的行为:
mysql> select a.name,d.name from a a right join d d on a.id=d.id;
+------+------+
| name | name |
+------+------+
| AA   | DA   |
| BB   | DB   |
| NULL | DC   |
| NULL | NULL |
+------+------+
4 rows in set (0.00 sec)
mysql> select a.name,d.name,a.id,d.id  from a a right join d d on
a.id=d.id;
+------+------+------+------+
| name | name | id   | id   |
+------+------+------+------+
| AA   | DA   |    1 |    1 |
| BB   | DB   |    2 |    2 |
| NULL | DC   | NULL | NULL |
| NULL | NULL | NULL |    5 |
+------+------+------+------+
4 rows in set (0.01 sec)

UNION

  • 使用UNION关键字将来自多个SELECT 语句的结果合并到单个结果集中
  • 每个SELECT 语句种的列数必须相同
  • 每个SELECT语句处于相同位置的列必须是兼容的数据类型
  • 默认为union DISTINCT,表示去重
  • UNION ALL保留重复的记录
  • 语法
query_1
union [ALL | DISTINCT]
query _2
mysql> select id from a union select id from b;
+------+
| id   |
+------+
|    2 |
|    1 |
|    3 |
+------+
3 rows in set (0.00 sec)

mysql> select id from a union all select id from b;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|    1 |
|    2 |
|    3 |
+------+
6 rows in set (0.02 sec)

差集(except)和交集(intersect)

mysql> select id from a except select id from c;
+------+
| id   |
+------+
|    3 |
+------+
1 row in set (0.01 sec)

mysql> select id from c except select id from a;
+------+
| id   |
+------+
|    4 |
+------+
1 row in set (0.00 sec)

mysql> select id from d except select id from a;
+------+
| id   |
+------+
|    5 |
| NULL |
+------+
2 rows in set (0.01 sec)

mysql> (select id from d except select id from a) order by id;
+------+
| id   |
+------+
| NULL |
|    5 |
+------+
2 rows in set (0.00 sec)

with 语句

针对复杂逻辑的SQL语句,with可以大幅减少临时表的数量。提升SQL代码的可读性和可维护性

with low_g_planets as ( 
select p.id,p.name,p.gravity 
from starts s
join planets p
on p.sun_id = s.id
where s.name = 'Sun' and p.gravity<10) 
select v1.name,v1.gravity,m.name from low_g_planets  as v1 left join moons m on v1.id=m.planet_id;

猜你喜欢

转载自blog.csdn.net/wangzhicheng987/article/details/131054842