首页 > 数据库 >(五)MySQL基础继续--连接(join)

(五)MySQL基础继续--连接(join)

时间:2022-10-04 11:03:02浏览次数:46  
标签:06 name -- 张三 28 29 2020 MySQL join

昨天在说MySQL的分组(group by)时,最后有提到为什么会多出来一行--> null, 原来null表示所有人加起来的数。

mysql> select name,sum(scores) as scores_count from teacher group by name with rollup;

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

| name   | scores_count |

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

| 张三   |          158 |

| 李四   |           88 |

| 柳九   |          100 |

| 王五   |           94 |

| 胡八   |           92 |

| 赵六   |           49 |

| NULL   |          581 |

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

7 rows in set (0.00 sec)


这个null看起来很难受,能不能显示为 总计、总量什么的呢?

答案是可以的。但是需要用到coalesce语法。语法为:

select coalesce(a,b,c);

如果a == null, 则选择b; 如果b==null,则选择c;如果a!=null,则选择a;如果a b c 都为null ,则返回为null。那么当name != null的时候,就显示用户的名字,如果名字为null时,就显示为 总数。其实和java里的循环很像。

我们来看看实例:

mysql> select coalesce(name,"总数"),sum(scores) from teacher group by name with rollup;

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

| coalesce(name,"总数")   | sum(scores) |

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

| 张三                    |         158 |

| 李四                    |          88 |

| 柳九                    |         100 |

| 王五                    |          94 |

| 胡八                    |          92 |

| 赵六                    |          49 |

| 总数                    |         581 |

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

7 rows in set (0.03 sec)

OK 好了!


接下来,说下MySQL中join的使用。这可是MySQL中的一个大重点!

先说下用法: 可以从多个数据库表中读取数据;

使用join在两个或多个数据库表中查询数据;

可以在 SELECT, UPDATE 和 DELETE 语句中使用 Mysql 的 JOIN 来联合多表查询。

join按照功能大致分为三大类:

inner join 内连接或等值连接: 获取两个表中字段匹配关系的记录 可以忽略inner 直接写 join

left join 左连接: 获取左表所有记录,即使右表没有对应匹配的记录

right join 右连接: 获取右表所有记录,即使左表没有对应匹配的记录


先看内连接 inner join

直接上实例: 

mysql> select * from teacher;

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

| id | name  | time  | scores |

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

| 1 | 张三  | 2020-06-28 |  77 |

| 2 | 李四  | 2020-06-28 |  88 |

| 3 | 王五  | 2020-06-28 |  66 |

| 4 | 赵六  | 2020-06-28 |  49 |

| 5 | 张三  | 2020-06-29 |  81 |

| 6 | 胡八  | 2020-06-29 |  92 |

| 7 | 柳九  | 2020-06-29 | 100 |

| 8 | 王五  | 2020-06-29 |  28 |

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

8 rows in set (0.01 sec)


mysql> select * from course;

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

| id | name  |

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

| 1 | 张三  |

| 2 | lucy  |

| 3 | jack  |

| 4 | Tom |

| 5 | Shanshan |

| 6 | Liulang |

| 7 | 胡扯  |

| 8 | 张三  |

| 9 | 李四  |

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

9 rows in set (0.00 sec)

我们通过和teacher、course有联系的name字段来获取对应的scores值

mysql> select a.id,a.name,a.time,a.scores,b.id,b.name from teacher a inner join course b on a.name = b.name;

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

| id | name  | time  | scores | id | name  |

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

| 1 | 张三  | 2020-06-28 |  77 | 1 | 张三  |

| 5 | 张三  | 2020-06-29 |  81 | 1 | 张三  |

| 1 | 张三  | 2020-06-28 |  77 | 8 | 张三  |

| 5 | 张三  | 2020-06-29 |  81 | 8 | 张三  |

| 2 | 李四  | 2020-06-28 |  88 | 9 | 李四  |

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

5 rows in set (0.00 sec)

我们可以看到对应的语法为:

select 你想显示的表名(多个表的都可以)对应的列名 from 数据库表a inner join 数据库表b on 两个数据库表之间的联系

inner join是交集,两个表中都有的东西,如下图

(五)MySQL基础继续--连接(join)_测试

我们试试把inner去掉,只要 join看看是不是结果也一样

mysql> select a.id,a.name,a.time,a.scores,b.id,b.name from teacher a join course b on a.name = b.name;

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

| id | name  | time  | scores | id | name  |

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

| 1 | 张三  | 2020-06-28 |  77 | 1 | 张三  |

| 5 | 张三  | 2020-06-29 |  81 | 1 | 张三  |

| 1 | 张三  | 2020-06-28 |  77 | 8 | 张三  |

| 5 | 张三  | 2020-06-29 |  81 | 8 | 张三  |

| 2 | 李四  | 2020-06-28 |  88 | 9 | 李四  |

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

5 rows in set (0.00 sec)


没错,结果是一样的

然后我们对结果再进行下优化,显示的数据有些重复,比如最后的id和name就显示重复了,没必要

mysql> select a.id,a.name,a.time,a.scores from teacher a join course b on a.name = b.name;

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

| id | name  | time  | scores |

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

| 1 | 张三  | 2020-06-28 |  77 |

| 5 | 张三  | 2020-06-29 |  81 |

| 1 | 张三  | 2020-06-28 |  77 |

| 5 | 张三  | 2020-06-29 |  81 |

| 2 | 李四  | 2020-06-28 |  88 |

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

5 rows in set (0.00 sec)


我们可以把数据库表b要显示的数据都删除掉,这样显示就好了很多

然后再核查下,数据显示的是否正确

teacher表和course表的name字段中,相同的有: 张三、李四

其中teacher表中,有2个张三,course表中有2个张三,结果表中有四个张三

teacher表中有1个李四,course表中没有李四,结果表中有1个李四

正确!

我们再来试试如果两个表中的字段不匹配,没有对应的值,会有什么结果

实例如下:

mysql> select a.id,a.name,a.time,a.scores from teacher a join course b on a.name = b.id;

Empty set (0.00 sec)

看吧,果然是空的~~哈哈


下面我们来看下 left join

left join 与 join 有所不同。MySQL LEFT JOIN 会读取左边数据表的全部数据,即便右边表无对应数据。

上面返回为空的例子拿到这里就很好,大家可以看下

mysql> select a.id,a.name,a.time,a.scores from teacher a left join course b on a.name = b.id;

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

| id | name  | time  | scores |

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

| 1 | 张三  | 2020-06-28 |  77 |

| 2 | 李四  | 2020-06-28 |  88 |

| 3 | 王五  | 2020-06-28 |  66 |

| 4 | 赵六  | 2020-06-28 |  49 |

| 5 | 张三  | 2020-06-29 |  81 |

| 6 | 胡八  | 2020-06-29 |  92 |

| 7 | 柳九  | 2020-06-29 | 100 |

| 8 | 王五  | 2020-06-29 |  28 |

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

8 rows in set (0.01 sec)

这是teacher表中所有的数据吗?

mysql> select * from teacher;

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

| id | name  | time  | scores |

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

| 1 | 张三  | 2020-06-28 |  77 |

| 2 | 李四  | 2020-06-28 |  88 |

| 3 | 王五  | 2020-06-28 |  66 |

| 4 | 赵六  | 2020-06-28 |  49 |

| 5 | 张三  | 2020-06-29 |  81 |

| 6 | 胡八  | 2020-06-29 |  92 |

| 7 | 柳九  | 2020-06-29 | 100 |

| 8 | 王五  | 2020-06-29 |  28 |

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

8 rows in set (0.00 sec)

嗯,没错,是的

如果两个数据库表的列有对应关系,会怎么样呢?

mysql> select a.id,a.name,a.time,a.scores from teacher a left join course b on a.name = b.name;

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

| id | name  | time  | scores |

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

| 1 | 张三  | 2020-06-28 |  77 |

| 5 | 张三  | 2020-06-29 |  81 |

| 1 | 张三  | 2020-06-28 |  77 |

| 5 | 张三  | 2020-06-29 |  81 |

| 2 | 李四  | 2020-06-28 |  88 |

| 3 | 王五  | 2020-06-28 |  66 |

| 4 | 赵六  | 2020-06-28 |  49 |

| 6 | 胡八  | 2020-06-29 |  92 |

| 7 | 柳九  | 2020-06-29 | 100 |

| 8 | 王五  | 2020-06-29 |  28 |

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

10 rows in set (0.00 sec)

就是把左边表中的数据和右边表中也符合a.name = b.name的数据加到了一起

(五)MySQL基础继续--连接(join)_数据库表_02


同样,right join 也是一样,会读取右边数据表的全部数据,即便左边边表无对应数据。

mysql> select a.id,b.name,a.scores from teacher a right join course b on a.name = b.name;

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

| id  | name  | scores |

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

| 1 | 张三  |  77 |

| 1 | 张三  |  77 |

| 2 | 李四  |  88 |

| 5 | 张三  |  81 |

| 5 | 张三  |  81 |

| NULL | lucy  |  NULL |

| NULL | jack  |  NULL |

| NULL | Tom |  NULL |

| NULL | Shanshan |  NULL |

| NULL | Liulang |  NULL |

| NULL | 胡扯  |  NULL |

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

11 rows in set (0.01 sec)

结果表就是 inner join结果+ 右表除了inner部分的数据,然后没有的数据补齐null


好的,今天就到这里


标签:06,name,--,张三,28,29,2020,MySQL,join
From: https://blog.51cto.com/u_11894/5731121

相关文章