加盟查询
在实际开发中,大多数情况下并不是从单表中查询数据,而是通常会联合查询多个表来得到最终的结果。
当信息存储在表中时,数据中会存在大量的重复,从而产生数据冗余。
按表的连接方式来划分,包括:
内连接:等连接、非等连接、自连接
外连接:左外连接(左连接) 右外连接(右连接)
全连接
表连接查询中有一种现象称为:笛卡尔积现象。 (笛卡尔积现象)
案例:找出每个员工的部门名称,要求显示员工姓名和部门名称。
EMP表中有员工姓名和部门编号,但没有部门名称。 部门名称位于 DEPT 表中。
如果连接两个表进行查询,如果没有条件限制,查询结果是两个表的乘积。
关于表别名:
e.ename,d.dname 来自 emp (as) e,dept (as) d;
表别名有什么好处?
第一:执行效率高。防止两个表有相同字段
第二:可读性好。
添加条件过滤笛卡尔积现象,
思考:如果避免了笛卡尔积现象,记录的匹配数会不会减少?
不是,次数还是56次,只是显示有效记录
e.ename,d.dname
从
员工,部门
在哪里
e. = d.;//SQL92,以后不会再用了。
内连接 等价连接
特征、条件是等价关系
案例:查询每个员工的部门名称,要求显示员工姓名和部门名称
// 内部可以省略。 使用inner的目的是为了使其更具可读性。
e.ename,d.dname 来自 emp e 内连接 e 上的部门 d。 = d。;
语法:
xxx 来自
表A
加入
表B
在
连接条件
在哪里
……
SQL99的语法结构更清晰:表的连接条件和后面的where条件分开
内连接非等值连接
连接条件中的关系是非等价关系
案例:查找每个员工的薪资等级,要求显示员工姓名、薪资、薪资等级。
e.ename,e.sal, s.grade 来自 emp e 加入 e.sal 上的 s
s.losal 和 s.hisal;
内连接 自连接
特点:一张表看成两张表,它们之间是相互连接的。
案例:找到每个员工的上级,要求显示该员工的姓名和对应领导的姓名。
empno,ename,mgr 形式 emp;
+-------+--------+------+
| empno | ename | mgr |
+-------+--------+------+
| 7369 | SMITH | 7902 |
| 7499 | ALLEN | 7698 |
| 7521 | WARD | 7698 |
| 7566 | JONES | 7839 |
| 7654 | MARTIN | 7698 |
| 7698 | BLAKE | 7839 |
| 7782 | CLARK | 7839 |
| 7788 | SCOTT | 7566 |
| 7839 | KING | NULL |
| 7844 | TURNER | 7698 |
| 7876 | ADAMS | 7788 |
| 7900 | JAMES | 7698 |
| 7902 | FORD | 7566 |
| 7934 | MILLER | 7782 |
+-------+--------+------+
a.ename as '员工姓名', b.ename as '领导姓名' from emp a join emp b on a.mgr =b.empno;
+--------+--------+
| 员工名 | 领导名 |
+--------+--------+
| SMITH | FORD |
| ALLEN | BLAKE |
| WARD | BLAKE |
| JONES | KING |
| MARTIN | BLAKE |
| BLAKE | KING |
| CLARK | KING |
| SCOTT | JONES |
| TURNER | BLAKE |
| ADAMS | SCOTT |
| JAMES | BLAKE |
| FORD | JONES |
| MILLER | CLARK |
+--------+--------+
外连接
内部联接:
假设A表和B表是连通的,使用内连接,可以查询到A表和B表中所有匹配的记录,这就是内连接。
主表AB 和副表AB 之间没有区别。 两个表是相等的。
外连接:
假设表A和B是连接的并且使用外部联接。 两张表AB其中一张为主表,一张为子表。 主要查询主表中的数据,也查询子表中的数据。 当子表中的数据与主表中的数据不匹配时,辅助表会自动模拟NULL来匹配。
外连接的分类?
左外连接(left join):表示左边的表为主表。
右外连接(right join):表示右边的表为主表。
左连接写成右连接的形式,右连接也写成相应的左连接的形式。
案例:找出每个员工的上级? (必须检查所有员工。)
上面的自连中,国王没有上位者,所以没有显示。 但如果一定要显示王,则需要外部连接。
左连接
a.ename as '员工姓名', b.ename as '领导姓名' from emp a left join emp b on a.mgr =b.empno;
join 之前有一个外部可以省略。
外连接最重要的特点是可以无条件查询主表中的所有数据。
案例:找出哪个部门没有员工?
d.* 从 d 部门左侧加入 emp e 于 e.=d。 其中 e.empno 为空;
连接三个表
案例:查询每个员工的部门名称和薪资等级。
……
加入
在
加入
在
……
表示:A表和B表先进行表连接,连接之后A表继续和C表进行连接。
e.ename,e. ,e.sal,d.dname ,s.grade 来自 emp e 左加入部门 d on e.=d。 将 s 加入 e.sal、s.losal 和 s.hisal;
案例:查出每个员工的部门名称、薪资等级、上级领导。
e.ename '员工',d.dname,s.grade,e1.ename '领导'
从
雇员
加入
部门
在
e. = d。
加入
s
在
e.sal s.losal 和 s.hisal
左连接
雇员 e1
在
e.mgr = e1.empno;
子查询
什么是子查询? 子查询可以出现在哪里?
语句嵌套在语句中,嵌套的语句是子查询。
子查询可以出现在哪里?
……()。
从
……()。
在哪里
……()。
1.在where子句中使用子查询
案例:查找高于平均工资的员工信息
第一步:找出平均工资
来自雇员的平均(萨尔);
第2步:where过滤
* 来自 emp,其中 sal > 2073。;
第一步和第二步合并:
* 来自 emp,其中 sal > (avg(sal) from emp);
2. from后面嵌套子查询
示例:查找每个部门的平均工资等级。
第一步:求各部门的平均工资(按照部门编号分组,求平均工资)
,avg(sal) 来自 emp 组 by ;
步骤2:将上述查询结果视为临时表t,并将t表和s表连接起来。 条件是: 和 s.hisal
t.*,s.级
从
( ,avg(sal) as from emp group by ) t //添加括号
加入
s
在
和 s.hisal;
示例:查找每个部门的平均工资等级。
第一步:了解每位员工的薪资等级。
ename ,,emp 的等级 e 加入 e.sal s.losal 和 hisal 上的 s; 作为t
步骤2:根据以上结果,继续分组,求平均成绩。
,来自 t 组的平均(成绩)
,平均(等级)来自(
ename ,,emp 的等级 e join s on e.sal s.losal 和 hisal) t group by ;
没有必要把它当作临时表,因为如果第一步查到了,就可以继续组查询。
ename ,,grade // 最初将左侧改为右侧 e.,avg(s.grade)
从
雇员
加入
s
在
e.sal s.losal 和 s.hisal
通过...分组
即;
3. 将子查询嵌套在后面。
案例:找出每个员工的部门名称,要求显示员工姓名和部门名称
原本的
e.ename,d.dname 来自 emp e 加入 e 上的 d 部门。 = d。;
我的想法
t.ename,d.dname from ( e.ename,e. from emp e) t 加入 t 上的部门 d。 =d。;
e.ename,( d.dname 来自 d 部门,其中 e. = d.) as dname
从
雇员 e;
union(查询结果集可以加在一起)
案例:找出员工的工作是?
第一个:ename,job from emp where job = '' or job = '';
第二种:ename,job from emp where job in('','');
第三种:联合体
ename,emp 的工作,其中 job = ''
联盟
ename,emp 的工作,其中 job = '';
两个不相关的表的数据拼接在一起显示?
来自 emp 的 ename
联盟
来自部门的 dname;
limit(关键点中的关键点,以后的分页查询都要靠它。)
Limit是MySQL独有的,其他数据库中没有,因此不具有通用性。 (有一个相同的机制,称为)
limit 取结果集中的部分数据
语法机制:
限制,
代表起始位置,从0开始,0代表第一条数据。
表示要带多少个
案例:按薪资取出前5名员工(思路:按降序取出前5名)
ename,sal 来自 emp 按 sal desc 排序;
ename,sal from emp order by sal desc limit 0, 5;//不写第一个0,默认是0,limit最后执行
案例:找出薪资排名第4到第9的员工?
ename,sal 来自 emp 订单,按 sal desc 限制 3,6;
常用标准分页sql
0、1、2、3、4、5、6、7、8、9
每页显示3条记录:
第1页:从0、3开始
第 2 页:从 3, 3 开始
第 3 页: 6, 3
第 4 页:9, 3
第 5 页:12, 3
每页显示n条记录:
第 m 页:(m - 1) * n, n
n是什么?每页显示多少条记录?
m是什么?显示哪个页面
java代码{
整数=2; //页码为2
整数=10; // 每页显示10条
限制 (- 1) * ,
DQL内容完成
表创建
建表语句语法格式:
表表名(
字段名称1数据类型,
字段名称2数据类型,
字段名称3数据类型,
……
);
MySQL中字段的数据类型有哪些?下面只说常见的
int 整数类型(java中的int)
长整数(java 中的 long)
float 浮点类型(java 中的 float)
char 定长字符串()
变长字符串 (/)
date 日期类型(对应Java中的java.sql.Date类型)
BLOB Large (存储图片、视频等流媒体信息) Large(对应java)
CLOB字符大对象(存储较大的文本,例如可以存储4G字符串。) Large(对应java)
……
char 和 如何选择?
实际开发中,当某个字段的数据长度不变时,就是定长。 比如性别、生日等都是char。
当字段的数据长度不确定时,如简介、名称等,则使用。
一般建议数据库中的表名以:t_或tbl_开头。
创建学生表:
学生信息包括:
学号、姓名、性别、班级、生日
学生卡:
姓名:
性别: 夏尔
类号:int
生日:字符/日期
create table t_student(
no bigint,
name varchar(255),
sex char(1),
classno varchar(255),
birth char(10)
);
语句插入数据
语法格式:
进入表名(字段名1,字段名2,字段名3,...)(值1,值2,值3,...)
要求:字段数量与值数量相同,数据类型必须相同。
drop table if exists t_student; // 当这个表存在的话删除。
桌子 (
不,
姓名 (255),
sex char(1) 1, //默认1
(255),
诞生炭(10)
);
插入时不给值,这里的性别会默认为1
注意事项:
当一条语句执行成功后,表中必然会多出一行记录。
即使这行记录中的某些字段为NULL,后面也没有办法执行它们。
该语句插入数据,只能用于更新。
//一次插入多行数据
进入
(否,姓名,性别,出生)