mysql连表查询left_MySQL联表查询基本操作之left-join常见的坑

8af8eac2eda5aa3ed317b53350551da0.png

概述

对于中小体量的项目而言,联表查询是再常见不过的操作了,尤其是在做报表的时候。然而校对数据的时候,您发现坑了吗?本篇文章就 mysql 常用联表查询复现常见的坑。

基础环境

建表语句

DROP TABLE IF EXISTS `role`;

CREATE TABLE `role` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`role_name` VARCHAR(50) DEFAULT NULL COMMENT "角色名",

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT="角色表";

insert into `role` VALUES(1, "管理员");

insert into `role` VALUES(2, "总经理");

insert into `role` VALUES(3, "科长");

insert into `role` VALUES(4, "组长");

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`role_id` int(11) NOT NULL COMMENT "角色id",

`user_name` VARCHAR(50) DEFAULT NULL COMMENT "用户名",

`sex` int(1) DEFAULT 0 COMMENT "性别",

PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT="用户表";

insert into `user` VALUES(1, 1, "admin", 1);

insert into `user` VALUES(2, 2, "王经理", 1);

insert into `user` VALUES(3, 2, "李经理", 2);

insert into `user` VALUES(4, 2, "张经理", 2);

insert into `user` VALUES(5, 3, "王科长", 1);

insert into `user` VALUES(6, 3, "李科长", 1);

insert into `user` VALUES(7, 3, "吕科长", 2);

insert into `user` VALUES(8, 3, "邢科长", 1);

insert into `user` VALUES(9, 4, "范组长", 2);

insert into `user` VALUES(10, 4, "赵组长", 2);

insert into `user` VALUES(11, 4, "姬组长", 1);

数据如下

mysql> select * from role;

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

| id | role_name |

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

| 1 | 管理员 |

| 2 | 总经理 |

| 3 | 科长 |

| 4 | 组长 |

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

4 rows in set (0.00 sec)

mysql> select * from user;

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

| id | role_id | user_name | sex |

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

| 1 | 1 | admin | 1 |

| 2 | 2 | 王经理 | 1 |

| 3 | 2 | 李经理 | 2 |

| 4 | 2 | 张经理 | 2 |

| 5 | 3 | 王科长 | 1 |

| 6 | 3 | 李科长 | 1 |

| 7 | 3 | 吕科长 | 2 |

| 8 | 3 | 邢科长 | 1 |

| 9 | 4 | 范组长 | 2 |

| 10 | 4 | 赵组长 | 2 |

| 11 | 4 | 姬组长 | 1 |

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

11 rows in set (0.00 sec)

基本业务

简单信息报表: 查询用户信息

mysql> SELECT

-> id,

-> user_name AS "姓名",

-> ( CASE WHEN sex = 1 THEN "男" WHEN sex = 2 THEN "女" ELSE "未知" END ) AS "性别"

-> FROM

-> USER;

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

| id | 姓名 | 性别 |

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

| 1 | admin | 男 |

| 2 | 王经理 | 男 |

| 3 | 李经理 | 女 |

| 4 | 张经理 | 女 |

| 5 | 王科长 | 男 |

| 6 | 李科长 | 男 |

| 7 | 吕科长 | 女 |

| 8 | 邢科长 | 男 |

| 9 | 范组长 | 女 |

| 10 | 赵组长 | 女 |

| 11 | 姬组长 | 男 |

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

查询每个角色名称及对应人员中女性数量

mysql> SELECT

-> r.id,

-> r.role_name AS role,

-> count( u.sex ) AS sex

-> FROM

-> role r

-> LEFT JOIN USER u ON r.id = u.role_id

-> AND u.sex = 2

-> GROUP BY

-> r.role_name

-> ORDER BY

-> r.id ASC;

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

| id | role | sex |

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

| 1 | 管理员 | 0 |

| 2 | 总经理 | 2 |

| 3 | 科长 | 1 |

| 4 | 组长 | 2 |

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

4 rows in set (0.00 sec)

假如我们把性别过滤的条件改为 where 操作结果会怎么样呢?

mysql> SELECT

-> r.id,

-> r.role_name AS role,

-> count( u.sex ) AS sex

-> FROM

-> role r

-> LEFT JOIN USER u ON r.id = u.role_id

-> WHERE

-> u.sex = 2

-> GROUP BY

-> r.role_name

-> ORDER BY

-> r.id ASC;

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

| id | role | sex |

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

| 2 | 总经理 | 2 |

| 3 | 科长 | 1 |

| 4 | 组长 | 2 |

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

3 rows in set (0.00 sec)

这里可以看到角色数据不完整了。

找出角色为总经理的员工数量

mysql> SELECT

-> r.id,

-> r.role_name AS role,

-> count( u.sex ) AS sex

-> FROM

-> role r

-> LEFT JOIN USER u ON r.id = u.role_id

-> WHERE

-> r.role_name = "总经理"

-> GROUP BY

-> r.role_name

-> ORDER BY

-> r.id ASC;

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

| id | role | sex |

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

| 2 | 总经理 | 3 |

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

1 row in set (0.00 sec)

同样将过滤条件由 where 改为 on

mysql> SELECT

-> r.id,

-> r.role_name AS role,

-> count( u.sex ) AS sex

-> FROM

-> role r

-> LEFT JOIN USER u ON r.id = u.role_id

-> AND r.role_name = "总经理"

-> GROUP BY

-> r.role_name

-> ORDER BY

-> r.id ASC;

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

| id | role | sex |

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

| 1 | 管理员 | 0 |

| 2 | 总经理 | 3 |

| 3 | 科长 | 0 |

| 4 | 组长 | 0 |

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

4 rows in set (0.00 sec)

这里可以看到数据多余了

总结

在 left join 语句中,左表过滤必须放 where 条件中,右表过滤必须放 on 条件中,这样结果才能不多不少,刚刚好。

到此这篇关于MySQL联表查询基本操作之left-join常见坑的文章就介绍到这了,更多相关MySQL联表查询left-join内容请搜索云海天教程以前的文章或继续浏览下面的相关文章希望大家以后多多支持云海天教程!

原文链接:https://juejin.im/post/5ebd5a8b51882573a924e2fd

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值