MySQL学习笔记(五)

版权声明:本文为自学而写,如有错误还望指出,谢谢^-^ https://blog.csdn.net/weixin_43871369/article/details/89531976

14. 联结表

14.1 联结

联结是利用SQL的select语句能执行的最重要操作

外键:外键是某个表得一列,它包含另一个表的主键值,定义了两个表之间的关系。

14.2 创建联结

mysql> select *from test;
+------+---------+------------------------------------+---------------------+
| t_id | t_name  | t_text                             | t_time              |
+------+---------+------------------------------------+---------------------+
|    5 | Tom     | This is a cat                      | 2019-04-25 16:13:39 |
|    4 | Jerry   | This is a mouse                    | 2019-04-25 15:40:55 |
|    6 | Helen   | She is a student in middle school. | 2019-04-25 16:13:39 |
|    1 | Helen   | NULL                               | 2019-04-25 16:17:21 |
|    3 | Helen   | NULL                               | 2019-04-25 16:17:21 |
|    7 | Erdison | NULL                               | 2019-05-04 00:00:00 |
|    8 | Linda   | NULL                               | 2019-04-02 12:00:00 |
|    9 | Lucy    | NULL                               | 2019-05-01 00:00:00 |
|   10 | Tomson  | NULL                               | 0196-04-23 00:00:00 |
+------+---------+------------------------------------+---------------------+
9 rows in set (0.00 sec)

mysql> select * from _test;
+------+--------+---------------------+
| t_id | _name  | _time               |
+------+--------+---------------------+
|    2 | Linda  | 2019-04-02 12:00:00 |
|    3 | Lucy   | 2019-05-01 00:00:00 |
|    4 | Tomson | 0196-04-23 00:00:00 |
+------+--------+---------------------+
3 rows in set (0.00 sec)

mysql> select t_name,t_time,_name
    -> from test,_test
    -> where test.t_id=_test.t_id
    -> order by t_name;
+--------+---------------------+--------+
| t_name | t_time              | _name  |
+--------+---------------------+--------+
| Helen  | 2019-04-25 16:17:21 | Lucy   |
| Jerry  | 2019-04-25 15:40:55 | Tomson |
+--------+---------------------+--------+
2 rows in set (0.00 sec)

务必要加上where语句,不然将会得到两个表的笛卡尔积,检索出来的行数将是第一个表中的行数乘以第二个表中的行数。

mysql> select t_name,t_time,_name
    -> from test,_test
    -> order by t_name;
+---------+---------------------+--------+
| t_name  | t_time              | _name  |
+---------+---------------------+--------+
| Erdison | 2019-05-04 00:00:00 | Linda  |
| Erdison | 2019-05-04 00:00:00 | Lucy   |
| Erdison | 2019-05-04 00:00:00 | Tomson |
| Helen   | 2019-04-25 16:17:21 | Linda  |
| Helen   | 2019-04-25 16:13:39 | Lucy   |
| Helen   | 2019-04-25 16:17:21 | Lucy   |
| Helen   | 2019-04-25 16:17:21 | Lucy   |
| Helen   | 2019-04-25 16:13:39 | Tomson |
| Helen   | 2019-04-25 16:17:21 | Tomson |
| Helen   | 2019-04-25 16:13:39 | Linda  |
| Helen   | 2019-04-25 16:17:21 | Tomson |
| Helen   | 2019-04-25 16:17:21 | Linda  |
| Jerry   | 2019-04-25 15:40:55 | Tomson |
| Jerry   | 2019-04-25 15:40:55 | Linda  |
| Jerry   | 2019-04-25 15:40:55 | Lucy   |
| Linda   | 2019-04-02 12:00:00 | Tomson |
| Linda   | 2019-04-02 12:00:00 | Linda  |
| Linda   | 2019-04-02 12:00:00 | Lucy   |
| Lucy    | 2019-05-01 00:00:00 | Tomson |
| Lucy    | 2019-05-01 00:00:00 | Linda  |
| Lucy    | 2019-05-01 00:00:00 | Lucy   |
| Tom     | 2019-04-25 16:13:39 | Tomson |
| Tom     | 2019-04-25 16:13:39 | Linda  |
| Tom     | 2019-04-25 16:13:39 | Lucy   |
| Tomson  | 0196-04-23 00:00:00 | Lucy   |
| Tomson  | 0196-04-23 00:00:00 | Tomson |
| Tomson  | 0196-04-23 00:00:00 | Linda  |
+---------+---------------------+--------+
27 rows in set (0.05 sec)

联结的表越多,性能下降的越厉害

14.3 内部联结

目前所用的联结称为等值联结,它基于两个表之间的相等测试。这种联结也称为内部联结。(可以加入inner join...on语句)

mysql> select t_name,t_time,_name
    -> from test inner join _test
    -> on test.t_id=_test.t_id;
+--------+---------------------+--------+
| t_name | t_time              | _name  |
+--------+---------------------+--------+
| Helen  | 2019-04-25 16:17:21 | Lucy   |
| Jerry  | 2019-04-25 15:40:55 | Tomson |
+--------+---------------------+--------+
2 rows in set (0.00 sec)

14.4 子查询和联结查询的相似之处

mysql> select t_name,t_time from test
    -> where t_id in( select t_id from
    -> _test where date(_time) between
    -> '0196-04-23' and '2019-04-23');
+--------+---------------------+
| t_name | t_time              |
+--------+---------------------+
| Jerry  | 2019-04-25 15:40:55 |
+--------+---------------------+
1 row in set (0.06 sec)

mysql> select t_name,t_time
    -> from test,_test
    -> where test.t_id=_test.t_id
    -> and date(_time) between
    -> '0196-04-23' and '2019-04-23';
+--------+---------------------+
| t_name | t_time              |
+--------+---------------------+
| Jerry  | 2019-04-25 15:40:55 |
+--------+---------------------+
1 row in set (0.00 sec)

可以看出子查询和联接查询结果一致,并且联接查询效率较为快一点,因此,对于一种查询往往存在不同的手段,查询效率受操作类型,表中数据量,是否存在索引或键以及其他一些条件的影响。

15. 创建高级联接

15.1 使用表别名

mysql> select t_name,t_time from
    -> test as t,_test as _t
    -> where t.t_id=_t.t_id
    -> and date(_time) between
    -> '0196-04-23' and '2019-04-23';
+--------+---------------------+
| t_name | t_time              |
+--------+---------------------+
| Jerry  | 2019-04-25 15:40:55 |
+--------+---------------------+
1 row in set (0.00 sec)

此例中,表test的别名为t。表别名只用于where子句。但是,表别名不仅能用于where子句,还可以用于select的列表、order by 子句以及语句的其他部分。应该注意的是,表别名只在查询执行中使用,与列别名不一样,表别名不返回客户机。

15.2 使用不同类型的联接

15.21 自联接

首先来看一个子查询例子

mysql> select t_name,t_time from
    -> test where t_id in(
    -> select t_id from test
    -> where date(t_time) between
    -> '2019-04-01' and '2019-04-23');
+--------+---------------------+
| t_name | t_time              |
+--------+---------------------+
| Linda  | 2019-04-02 12:00:00 |
+--------+---------------------+
1 row in set (0.02 sec)

可以将上例转换为相同查询的自联结的形式如下

mysql> select t1.t_name,t1.t_time from
    -> test as t1,test as t2
    -> where t1.t_id=t2.t_id
    -> and date(t2.t_time) between
    -> '2019-04-01' and '2019-04-23';
+--------+---------------------+
| t_name | t_time              |
+--------+---------------------+
| Linda  | 2019-04-02 12:00:00 |
+--------+---------------------+
1 row in set (0.06 sec)

15.22 自然联接

扫描二维码关注公众号,回复: 6070352 查看本文章

无论何时对表进行联结,应该至少有一个列出现不止一个表中(被联结的列)。自然联结就是排出多次出现,使每个列只返回一次。一般通过对表使用通配符(select *),对所有其他表的列使用明确的子集来完成。

mysql> select t.*,_t._name,_t._time
    -> from test as t,_test as _t
    -> where t.t_id=_t.t_id;
+------+--------+-----------------+---------------------+--------+------------
-------+
| t_id | t_name | t_text          | t_time              | _name  | _time
       |
+------+--------+-----------------+---------------------+--------+------------
-------+
|    3 | Helen  | NULL            | 2019-04-25 16:17:21 | Lucy   | 2019-05-01
:00:00 |
|    4 | Jerry  | This is a mouse | 2019-04-25 15:40:55 | Tomson | 0196-04-23
:00:00 |
+------+--------+-----------------+---------------------+--------+------------
-------+
2 rows in set (0.00 sec)

迄今为止,我们建立的所有内部联结都是自然连接。

15.23 外部联结

mysql> select test.t_id,_test._name
    -> from test left outer join _test
    -> on test.t_id=_test.t_id;
+------+--------+
| t_id | _name  |
+------+--------+
|    3 | Lucy   |
|    4 | Tomson |
|    1 | NULL   |
|    5 | NULL   |
|    6 | NULL   |
|    7 | NULL   |
|    8 | NULL   |
|    9 | NULL   |
|   10 | NULL   |
+------+--------+
9 rows in set (0.00 sec)
mysql> select test.t_id,_test._name
    -> from test right outer join _test
    -> on test.t_id=_test.t_id;
+------+--------+
| t_id | _name  |
+------+--------+
| NULL | Linda  |
|    3 | Lucy   |
|    4 | Tomson |
+------+--------+
3 rows in set (0.00 sec)

从上面两个例子可以看出,left outer join...on和right outer join...on的区别在于left...将会列出from后左边表的所有行,右边表与之不匹配的输出为NULL。right与之相反。

15.3 使用带聚集函数的联结

mysql> select _test.t_id,_test._name,
    -> count(test.t_name) as t_cntname
    -> from _test inner join test
    -> on _test.t_id=test.t_id
    -> group by _test.t_id;
+------+--------+-----------+
| t_id | _name  | t_cntname |
+------+--------+-----------+
|    3 | Lucy   |         1 |
|    4 | Tomson |         1 |
+------+--------+-----------+
2 rows in set (0.06 sec)
mysql> select test.t_id,_test._name,
    -> count(test.t_name) as t_cntname
    -> from test left outer join _test
    -> on test.t_id=_test.t_id
    -> group by test.t_id;
+------+--------+-----------+
| t_id | _name  | t_cntname |
+------+--------+-----------+
|    1 | NULL   |         1 |
|    3 | Lucy   |         1 |
|    4 | Tomson |         1 |
|    5 | NULL   |         1 |
|    6 | NULL   |         1 |
|    7 | NULL   |         1 |
|    8 | NULL   |         1 |
|    9 | NULL   |         1 |
|   10 | NULL   |         1 |
+------+--------+-----------+
9 rows in set (0.06 sec)

猜你喜欢

转载自blog.csdn.net/weixin_43871369/article/details/89531976