一、简单的查询语句
**Select**``**字段名,字段名**``** from **``**表名;**
- 任何一个SQL语句以分号结尾。
- SQL语句不区分大小写
数据支持运算**Select * from **``**表名**
查询全部字段(不建议使用,效率低)
1、给查询出来的结果起别名
Select ename '别名' from emp;
Select ename as '别名' from emp;
标准SQL语句中 要求字符串用单引号,尽量不要用””
二、条件查询
Select ③
字段名,字段名
From ①
表名
Where ②
条件;
1、运算符
- < > <= >= 【!= \ <> 不等于】 =等于
- mysql中的等于判断是 = 一个等于
- Between.小. and.大.. [都是闭区间]
**Is null**
为null
,**is not null**
不为null
- And or not
- in 包含
- 等同于 or
select * from emp where job = 'manager' or job = 'salesman';
select * from emp where job ``**in('manager','salesman');**
- 注意:不是区间,而是具体的值
- 等同于 or
Not in
不在这几个值当中**Not **
可以取非**Like **
模糊查询 %表示多个字符 _表示单个字符 转义字符 \在数据库中 null不是一个值,代表为空,啥也没有
- Null 不能用=号衡量,可以使用 <=>,is null, is not null
- and优先级要比or高,当运算符优先级不确定的时候加 ()
3、示例
select * from emp where job = 'manager' or sex = 'man'
select * from emp where sal > 1000 and (deptno = 20 or deptno = 30);
select * from emp where ename like '%o%';
三、排序
升序asc 降序desc)
Select ③
字段名,字段名
From ①
表名
Where ②
条件
Order by ④
????;
- 默认是升序
- 按照编号降序
select * from emp order by empno desc;
按照工资升序,工资一样,按名字降序(多个字段排序)select * from emp ``**order by sal asc,ename desc;**
:::info
多个字段排序: 越靠前的作用越大
:::
**Select ename , sal from emp order by 2;(``不建议使用``)
表示用第二列来排序 就是用sal排序
四、分组函数/多行处理函数
输入多行 输出一行
- Count()计数
- Sum() 求和
- Avg() 求平均值
- Max() 最大值
- Min() 最小值
所有的分组函数都是对“某一组”数据进行操作的
分组函数** 自动忽略 null;
分组函数不可直接使用在where子句当中(绝对直接出现在where后面)**
原因 :因为分组函数是在group by 后面执行,而group by是在where执行完才执行
1、Count(*)和count(字段)有什么区别?
Count(*) 统计的一定是总个数
Count(字段) 统计的是该字段中不为null的数据总个数
五、单行处理函数
数学表达式中有null的出现,不管如何结果都是null,可使用ifnull()避免
Concat(字段一,字段二) 字符串拼接
Distinct 字段 去重
- Distinct 只能出现在所有字段的最前面(表示后面所有的字段联合起来去重)
- Select distinct job , ename from emp;
- 统计岗位的数量
- Select count(distinct job) from emp;
六、分组查询
- group by ..having..
- Group by 按照某个/某些字段进行分组
- Having 对分组之后的数据 进行在次过滤
找出每个工作岗位的最高薪资Select ⑤
字段名,字段名
From ①
表名
Where ②
条件
Group by ③
分组条件
Having ④
条件
Order by ⑥
升降序
Select ``**max(sal),job **``from emp ``**group by job;**
先from之后分好组在查询最大值
(多个字段联合起来分组)找出每个部门不同工作岗位的最高薪资Select ``**max(sal),deptno,job**``from emp group by ``**deptno,job;**
1、注意:分组函数一般都和group by联合使用
- 所以分组函数永远都是在group by 之后在执行
- 当一条sql语句没有group by之后,整张表的数据会自成一组。(会有一个缺省的group by)
2、当一条语句有group by 的时候 select后面只能出现被分组的字段或者是分组函数
也就是说 select ename,max(sal),job from emp group by job; ename出现不合理
3、Having 分完组再过滤
找出每个部门的平均工资,要求显示薪资大于2000的数据select avg(sal) as``**pingjun**``,deptno from emp group by deptno ``**having pingjun >2000**``;
Where和having的使用?
- 如果数据是在可以在分组前就进行过滤的话,那么就先用where过滤
- 如果数据是只能分组后才能过滤的话,那么就用having过滤(只能出现在group by 后面)
七、总结:
执行顺序:
Select 5
….
From 1
….
Where 2
….
Group by 3
….
Having 4
….
Order by 6
….
八、连接查询
1、什么是连接查询?
根据表的连接方式来划分为
- 内连接
- 等值连接
- 非等值连接
- 自连接
- 外连接
- 左外连接
- 右外连接
-
3、笛卡尔乘积现象
两张表进行连接查询,没有任何条件进行限制,最后的结果是两张表条数的乘积
Select ename,dname from emp,dept;
原理:A表中的ename和B表中的dname进行匹配,但是没有条件限制,就出现了全部匹配(乘积现象)
1)关于表的别名
Select e.ename,d.dname from ``**emp e, dept d**
- 直接在表后面加空格 别名
- 表别名的好处:
(92语法)查询每个员工的部门名称
Select
e.ename,d.dname # 查询员工名 和 部门名
From
Emp e, dept d # 别名
Where
e.deptno = d.deptno #有效的条件限制,e表中的部门编号 要等于 d表中的部门编号
3)添加了条件之后,会减少记录的匹配次数吗?
不会,次数还是乘积的那个次数,不过显示的是有效的匹配记录
4、内连接中的等值连接 inner join..on
- 连接条件是等量关系
查询每个员工的部门名称 (99 语法常用)
Select
e.ename,d.dname
From
Emp e
【inner】join #连接 inner可省略
dept d
On
e.deptno = d.deptno #on后面添加连接条件
为什么99语法要比92好?
99语法中表连接的条件和where条件分离了,结构更清晰
5、内连接中的非等值连接 inner join..on
连接条件是非等量关系
找出每个员工的工资等级,要求显示员工名,工资,工资等级
Select
e.ename,e.sal,s.grade
From
Emp e
Join
Salgrade s
On
e.sal between s.losal and s.hisal;
6、自连接
一张表看作两张表,自己连自己
找出每个员工的上级领导,显示员工名,领导名
Select
e.ename as '员工',ee.ename as '领导'
From
Emp e
Join
Emp ee
On
e.mgr = ee.empno;
九、外连接(开发中使用较多)
1、什么是外连接,和内连接有什么不同
- 内连接:A和B表进行内连接,使用内连接的话凡是A表和B表能够匹配上的记录查询出来。
- AB两张表没有主副之分(如果匹配不上,则会丢失数据)
外连接:A和B进行外连接,A和B中有一个是主表,有一个是副表,主要查询主表中的数据,如果副表中没有匹配上的,则会匹配null。
2、分类
左外连接【左边是主表】
- 右外连接【右边是主表】
3、左外连接
查询每个员工的上级领导(所有员工)
Select
e.ename,ee.ename
From
Emp e #(主表)
Left join #如果从副表中查询不到的话,会匹配null, 保证了主表数据的完整性
Emp ee #(副表)
On
e.mgr = ee.empno;
找出那个部门没有员工
select
d.dname,e.ename
from
dept d
left join # 部门表做主表
emp e
on
d.deptno = e.deptno
Where
e.Ename is null;
4、右外连接
查询每个员工的上级领导(所有员工)
select
e.ename,ee.ename
from
emp ee #(副表)
right outer join #outer可省略
emp e #(主表)
on
ee.empno = e.mgr;
十、三张表怎么查询
from
A
Join
B
On
….
Join
C
On
….
表示A表先和B表进行表连接,连接之后在和B表做连接
查询每个员工的部门名称和工资等级,和上级领导
select
e.ename,d.dname,s.grade,ee.ename
from
emp e
join
dept d #连接部门表,查部门名称
on
e.deptno = d.deptno
join
salgrade s # 连接工资表,查工资等级
on
e.sal between s.losal and s.hisal
Left Join
Emp ee #左外连接自己(自连接)查领导
On
e.mgr = ee.empno;
多对多的关系,三张表,用户表、身份表、用户身份关系表
查询每个人的信息和身份
SELECT
u.*,r.*
FROM
USER u
JOIN
user_role ur #连接关系表 条件是用户表的id等于关系表的uid
ON
u.id = ur.uid
JOIN
role r ##连接身份表 条件是身份表的id等于关系表的rid
ON
r.id = ur.rid
十一、子查询
1、什么是子查询?都能出现在哪里
select语句中嵌套一个子查询,被嵌套的就是子查询
子查询可以出现在
Select
…(select)
From
…(select)
Where
…(select)
2、where子句中,使用子查询
找出高于平均薪资的员工
select
*
from
emp
where
sal>(select avg(sal) from emp);
3、from后面嵌套子查询
找出每个部门平均薪水的薪资等级
Select
s.grade,e.avgsal,e.deptno
From
(Select avg(sal) as avgsal,deptno from emp group by deptno) e
Join
Salgrade s
On
e.avgsal between losal and hisal;
在from后面的子句中用括号括起来,表示起了一个别名e
----------------------------------------------------------------
(这种情况不需要用子查询)找出每个部门薪资等级的平均值
select
e.deptno,avg(s.grade)
from
emp e
join
salgrade s
On
e.sal between losal and hisal
Group by
e.deptno;
4、Select 后面嵌套子查询
查询每个员工的姓名和部门名称(使用子查询)
Select
e.ename,
(select d.dname from dept d where e.deptno = d.deptno) as dname
From
Emp e
注意事项:
- 最好给每个字段都其上别名
- 给子查询语句用括号括起来 起一个别名