day4:MySQL基础sql语句DQL(多表查询,子查询)
一、MySQL四大主要设计语言
- DDL 数据库定义语言
- DML 数据操作语言
- DQL 数据库查询语言
- DCL 数据库权限语言
DQL(data query language)数据查询语言(续)
承接DQL的内容,继续补充多表查询。
在以后的使用中,我们对于数据的不用会紧紧局限于单张表中的数据。那学生表举例子,我们通过学生的id获得了他在学生数据表中的成绩,那么我们也能通过id获得学生对应课程的成绩。那么将两个结果结合在一起,可以一个语句里面对两个表一起查询。
先在一个sql创建个多表数据库,方便接下来的多表查询。
SET NAMES UTF8; DROP DATABASE IF EXISTS base; CREATE DATABASE IF NOT EXISTS base CHARSET=UTF8; USE base; #学生表 CREATE TABLE student( s_id INT PRIMARY KEY AUTO_INCREMENT,#学生编号主键自增 s_name VARCHAR(6) NOT NULL,#学生姓名不可为空 sex BOOL#学生性别0女1男 ); #课程表 CREATE TABLE class( c_id INT PRIMARY KEY AUTO_INCREMENT,#课程编号主键自增 c_name VARCHAR(12) NOT NULL,#课程名不可为空 t_id INT#教师编号 ); #教师表 CREATE TABLE teacher( t_id INT PRIMARY KEY AUTO_INCREMENT,#教师编号主键自增 t_name VARCHAR(6) NOT NULL#教师姓名不可为空 ); #成绩表 CREATE TABLE score( s_id INT,#学生编号 c_id INT,#课程编号 score TINYINT#课程成绩 ); #插入学生数据 INSERT INTO student VALUES(NULL,'张三',0); INSERT INTO student VALUES(NULL,'李四',1); INSERT INTO student VALUES(NULL,'王五',0); #插入教师数据 INSERT INTO teacher VALUES(NULL,'赵一孙'); INSERT INTO teacher VALUES(NULL,'钱一孙'); INSERT INTO teacher VALUES(NULL,'孙一'); #插入课程数据 INSERT INTO class VALUES(NULL,'语文',1); INSERT INTO class VALUES(NULL,'数学',2); INSERT INTO class VALUES(NULL,'英语',3); #插入成绩数据 INSERT INTO score VALUES(1,1,60); INSERT INTO score VALUES(1,2,80); INSERT INTO score VALUES(1,3,90); INSERT INTO score VALUES(2,1,80); INSERT INTO score VALUES(2,2,null);#null表示缺考 INSERT INTO score VALUES(2,3,90); INSERT INTO score VALUES(3,1,null); INSERT INTO score VALUES(3,2,80); INSERT INTO score VALUES(3,3,null);
扔到小黑板运行一下,一个简陋的数据库就做好了。
接下来就开始讲解多表查询。
首先规范一下用于
在单表查询的时候我们直接使用了列名作为查询项。那么在多表查询中建议使用表名.列表名作为查询项,一来是万一表中有重复列名会影响查询,有表名的列更方便电脑查询。
语句都是一样的,从最简单的SELECT…FROM 开始
查询出同学的姓名与他的成绩,先不使用WHERE 条件我们看一下查询结果。
我们发现student中的三条数据与score中每一条数据都进行了一次匹配,这种现象叫做笛卡尔积,有兴趣的可以链接了解一下。
那么如何解决呢。两张表中共有的属性是s_id(学生编号),那么我们定义条件学生表中的编号与成绩表中的相等,WHERE student.s_id=score.s_id。
显然多变查询只是比单表查询多了一个数据匹配的条件。
那么结合一道综合题,来讲述一下子查询。
查询总成绩的平均数在70及以上的学生的最高分的成绩
1.首先我们要知道满足条件的学生的编号
SELECT student.s_id,student.s_name,AVG(score.score) FROM student,score WHERE student.s_id=score.s_id GROUP BY student.s_id HAVING AVG(score.score)>=70;
第一个坑就来了。
怎么每个人都出来了呢,李四只考了二门,王五只有一门,怎么还和全考了的张三一起成了本次成绩良好学生了。明显使用AVG时忽略了NULL,所以换一种思路,平均70,那么总和210,所以改HAVING为SUM(score.score)>=210.
结果就只有张三一个人了。
2.我们知道了学生编号是1的张三满足了条件,然后我们要知道他最高分数的成绩是多少
SELECT MAX(score) FROM score WHERE s_id=1;
条件中的1是我们第一次查询出的结果,所以可以看作一个整体,用()表示一个整体
然后填入上面的代码。
SELECT MAX(score) FROM score WHERE s_id IN ( SELECT student.s_id FROM student,score WHERE student.s_id=score.s_id GROUP BY student.s_id HAVING AVG(score.score)>=70 );
s_id IN ()表示s_id是()中的一个值。
也就是s_id是满足()查询条件的值。
这种查询嵌套就是子查询了。
内连接、外连接、全连接
上面的from student,score是MySQL中的普通多表查询,它根据我们给出的条件对两个表进行数据匹配。形象的来说就是两个圆相交的部分是它结合的结果,如下图所示
举个栗子,比如员工表和部门表。
老板没有部门,但是他是个员工。
老板没有部门在员工表录入的部门编号就是Null
匹配的时候就查不出来。
查询结果
很明显没有了部门的老板Jerry不能出现在查询结果之中。
所以我们需要新的连接方式,帮助插叙。
先补充一下概念
内连接
内连接是从结果表中删除与其他被连接表中没有匹配行的所有行,所以内连接可能会丢失信息。
内连接与普通连接结果也一样。
我们需要的是外连接
外连接分为三种:左外连接,右外连接,全外连接(mysql不支持)
语法
SELECT * FROM t1 LEFT OUTER JOIN t2 ON 条件;#左连接
SELECT * FROM t1 RIGHT OUTER JOIN t2 ON 条件;#右连接
OUTER可以省略
我们通过查询结果来了解一下两者的区别。
为了使两者结果更鲜明,将右外连接的查询条件改为不等于。
我们能发现左连接是将左表的数据作为基础,与右标数据进行匹配。不存在的数据以Null表示。右连接则相反。
那么如果我都要呢,MySQL又不支持外全连接。所以使用UNION将左连接与右连接结果联合。
(SELECT * FROM emp LEFT JOIN dept ON emp.dept_id=dept.d_id)
UNION
(SELECT * FROM emp RIGHT JOIN dept ON emp.dept_id!=dept.d_id)
union默认是DISTINCT不重复。
可以在union后面加all查询所有数据
- MySQL (五)上 DQL 数据查询语言(sql 语句)
- 关于mysql查询语句基础SQL
- MySQL 基础架构 1. 一条SQL查询语句的执行过程(个人学习笔记)
- MySql(4)------SQL基础之DML(Data Manipulation Language)下的查询(select)语句
- web day15 数据库概述,MySQL,SQL语句,数据查询语法DQL
- 极客时间 MySQL实战45讲:01 | 基础架构:一条SQL查询语句是如何执行的?
- MySQL 使用explain分析sql语句的查询效率
- 浅谈MySQL中优化sql语句查询常用的30种方法
- mysql、MS SQL关于分页的sql查询语句 limit 和row_number() OVER函数
- Hibernate SQLQuery查询返回空List,在mysql命令下直接执行sql语句可以正常得到记录
- mysql的sql语句中字符串作为字段查询
- mysql基础-- 一条请求执行多条SQL语句
- Linux命令:MySQL系列之三--mysql数据类型及SQL结构化查询语句使用
- mysql的sql语句根据经纬度查询距离排序
- mysql补充(3)优化sql语句查询常用的30种方法
- MySQL入门(1)- SQL语句分类&查询语句
- MySQL常用SQL语句总结包含复杂SQL查询
- MySQL常用30种SQL查询语句优化方法
- MySQL学习笔记(一):基础常用SQL语句
- MYSQL学习心得(1)--基础SQL语句