mysql关联查询图解_mysql 关联查询技巧

废话不多说,直接进入正题

#数据准备

班级表class:

CREATE TABLE`class` (

`class_no`int(2) unsigned zerofill NOT NULL AUTO_INCREMENT COMMENT '班级编号',

`class_name`varchar(30) CHARACTER SET utf8 NOT NULL COMMENT '班级名称',PRIMARY KEY(`class_no`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1;insert into class values(1, '培优班');insert into class values(2, '普通班');insert into class values(3, '提升班');

学生表student:

CREATE TABLE`student` (

`stu_no`int(2) unsigned zerofill NOT NULL AUTO_INCREMENT COMMENT '学员编号',

`stu_name`varchar(30) CHARACTER SET utf8 NOT NULL COMMENT '学员姓名',

`stu_sex`varchar(3) CHARACTER SET utf8 NOT NULL COMMENT '学员性别',

`stu_age`tinyint(2) unsigned zerofill DEFAULT NULL COMMENT '学员年代',

`grade`double(5,2) unsigned zerofill DEFAULT NULL COMMENT '成绩',

`class_no`int(2) unsigned zerofill DEFAULT NULL COMMENT '所在班级编号',PRIMARY KEY(`stu_no`),KEY`class_no` (`class_no`)

) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1;insert into student values(01, '李白', '男', 18, 60, 01);insert into student values(02, '杜甫', '男', 20, 76, 01);insert into student values(03, '张飞', '男', 32, 80, 02);insert into student values(04, '韩信', '男', 26, 98, 02);insert into student values(05, '了龙', '男', 27, 56, 02);insert into student values(06, '大乔', '女', 17, 88, 01);insert into student values(07, '小乔', '女', 16, 96, 01);insert into student values(08, '小乔', '女', 16, 90, 01);insert into student values(09, '关哥', '男', 32, 80, 02);insert into student values(10, '刘备', '男', 36, 98, null);

1: exists子查询

如果子查询有返回结果则为true,如果没有返回值则为false

select * from student where exists(select * from student where grade = 80)

9fcfd10b7cee6f428ade6071bf78f2da.png

比如not exists:

select * from student where not exists(select * from student where grade = 80);

以上结果返回空,因为 not exists 返回了 false

select * from student where exists (select * from class where class.class_no = student.class_no);

44f39942cb07e76cb9fc3a7acb2d8ae6.png

上面的查询可以看到,我们少了一条数据,第十条的clas_no 是null。。。所以这条数据是flase....而

class.class_no = student.class_no 为true的,就全部返回了

2: [union] 并合查询

需求: 拿到01班级的最高成绩 和 02班级的最低成绩

我们一般会这样

select max(grade) from student where class_no = 01;select min(grade) from student where class_no = 02;

优化这个查询我们可以这样:

(select concat('1号班级最高成绩:', max(grade)) '成绩' from student where class_no = 01)union(select concat('2号班级最低成绩:', min(grade)) '成绩' from student where class_no = 02);

e6757d0660acbb52853cfd710d5ee2bd.png

这里再说下union 和union all的区别:

union:

(select class_no, stu_name, stu_age from student where class_no = 1)union(select class_no, stu_name, stu_age from student where class_no = 2);

cda8bd7ffc57555f25f3f67f877a7c99.png

union all:

(select class_no, stu_name, stu_age from student where class_no = 1)union all(select class_no, stu_name, stu_age from student where class_no = 2);

8fbce66530269b2b891397c156c3ca87.png

通过以上两个查询,我们可以看到:union并合查询它会自动的去重复的记录, 如果不想要去掉重复的记录则可以使用 union all;

我们加个排序:

(select class_no, stu_name, stu_age from student where class_no = 1)union all(select class_no, stu_name, stu_age from student where class_no = 2) order by stu_age desc;

b9d2287664cf3ec915060b326c0a8a5c.png

连接查询的分类

1: 内连接

2: 外连接

3: 自然连接

1: inner join(内连接)

需求: 查询出学员的学号, 姓名, 所在的班级名称

select stu_no, stu_name, class_name from student join class where `student`.class_no = `class`.class_no;

002b3c236bd677d26e874d85f261e0a8.png

以上sql等同于:

select stu_no, stu_name, class_name from student join class where `student`.class_no =`class`.class_no;select stu_no,stu_name,class_name from student,class where student.class_no = class.class_no;

内连接的inner字符可以不用写

2: cross join(交叉连接,迪卡尔集) 没有条件的内连接

例: select * from student cross join class;

例: select * from student inner join class;

例: select * from student cross join class where `student`.class_no = `class`.class_no;

ps: cross join 与 inner join 在使用上没有区分,只是在mysql中把cross join定义成交叉连接而已

就写到这把。。其他的连接方式也简单,资料也很多啦。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值