(一)普通查询
1.1基础查询
- 查询语句(包括查询常量、表达式、函数):
select 内容 from 表名
其中内容可以是*,可以是1+1,可以是10,可以是一个函数 - 起别名和去重
select 内容 as 内容别名 from 表名
如果需要去掉重复
SELECT DISTINCT 内容as 内容别名from 表名; - 字符串拼接(解决拼接过程中值为null):使用Concat()函数
select concat(last_name,first_name) as 姓名 FROM employees;
在字符串拼接时,如果字符串中值有空值,则整个查询为空值,所以使用IFNULL来进行筛选
select IFNULL(commission_pct,0) FROM employees;
第一个参数表示哪个列,第二个参数表示如果是null 则赋值为某个值
1.2条件查询
- 条件查询语句select
查询内容 from 表名 where - 逻辑运算符与条件表达式
< >= <= = != <>
and(&&):两个条件如果同时成立,结果为true,否则为false
or(||):两个条件只要有一个成立,结果为true,否则为false
not(!):如果条件成立,则not后为false,否则为true
1.3模糊查询
1.3.1 LIKE
- 查询语句
select 内容 from 表名 where 内容like (一般使用通配符) - 通配符
%表示匹配任意多个字符,包含0个字符
_表示匹配任意单个字符。 - 查询员工名中包含字符a的员工信息
select * from empleyees where last_name LIKE '%a%'
- 查询员工名中第三个字符为e,第五个字符为a的员工名和工资
select last_name,salary from empleyees where Last_name LIKE '__e_a%'
- 转义字符
查询第二个字符是下划线的员工信息。
select last_name,salary from empleyees where Last_name LIKE '_\\\_ %'
select last_name,salary from empleyees where Last_name LIKE '\_\$\_ %' ESCAPE '\$\'
1.3.2 BETWEEN AND
- 查询语句
select 内容 from 表名 where BETWEEN A ADN B - 通配符
A与B值不能调换
1.3.2 IN
- 查询某字段的值是否属于某一列。主要是来替换or。in列表的值类型必须一致
- 查询语句:查训工作编号为IT_PROT’,'AD_VP’两个的员工姓名与工作编号
select 内容 last_name ,job_id from where job_id IN(‘IT_PROT’,‘AD_VP’); - 不支持通配符
1.3.3 IS_NULL与安全等于
- =、<> 无法判断null值,使用is_null来进行判断
SELECT last_name,commission_pct FROM employees where ISNULL(commission_pct) - 安全等于<=>:判断是否等于,可以查到null值,也可以查看普通数值。
1.4排序查询
- 查询语句:
select 查询列表 from 表名 [where] order by 排序列表[dec|asc] - asc升序 默认是升序。这个语句一般放在最后面,除了limit语句
- 按照条件查询排序
查询部门编号>=90的员工信息,并按员工编号降序
SELECT *FROM employees WHERE department_id>=90 ORDER BY employee_id DESC; - 按照表达式排序
查询员工信息 按年薪降序
select * ,salary12(1+IFNULL(commission_pct,0)) as 年薪 FROM employees ORDER BY salary12(1+IFNULL(commission_pct,0)) DESC; - 按照别名排序
查询员工信息 按年薪降序
select * ,salary12(1+IFNULL(commission_pct,0)) as 年薪 FROM employees ORDER BY 年薪 DESC; - 按照函排序
查询员工名,并且按名字的长度降序
SELECT LENGTH(last_name),last_name FROM employees ORDER BY LENGTH(last_name) DESC; - 按照多个字段排序
查询员工信息,要求先按工资降序,再按employee_id升序
SELECT * FROM employees ORDER BY salary DESC,employee_id ASC;
(二)分组查询
用于求出某些相同字段的数据,通常与分组函数搭配使用
1.1普通分组查询
SELECT MAX(salary),manager_id FROM employees GROUP BY manager_id;
1.2增加筛选条件(分组前的筛选)
分组前的筛选:筛选的数据源是已经有的表
使用where增加筛选条件
查询不同老板下员工奖金率不为null的最大工资。
SELECT MAX(salary),manager_id FROM employees where commission_pct IS NOT NULL
GROUP BY manager_id;
1.3使用HAVING实现分组后筛选
分组前的筛选:筛选的数据源是分组后的数据表
查询哪个部门的员工个数>2
能用分组前筛选就用分组前筛选
select COUNT(*),department_id FROM employees
GROUP BY department_id
HAVING COUNT(*)>2;
SELECT MAX(salary) ,job_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id;
HAVING MAX(salary)>12000
1.4使用表达式函数作为分组条件
按照姓名长度进行分组,查询每一组员工的个数,筛选员工个数大于五的有哪些
SELECT COUNT(*),LENGTH(last_name) AS len_name
FROM employees
GROUP BY LENGTH(last_name)
HAVING count(*)>5
1.5按多个字段进行分组,增加排序
查询每个部门,每个工种员工的平均工资
select AVG(salary),job_id,department_id from employees
GROUP BY job_id,department_id
order by AVG(salary) desc
(三)连接查询
连接查询的分类
按功能分类:
- 内连接
等值连接
非等值连接
自连接 - 外连接
左外连接
右外连接
全外连接 - 交叉连接
----------------92语法-----------------------
3.1内连接
3.1.1等值连接
使用where来进行限定查询条件
显示交集
select e.last_name,e.job_id,job_title
FROM employees e,jobs j
where e.job_id=j.job_id;
使用and加筛选条件
select e.last_name,d.department_id,department_name
from employees e ,departments d
where e.department_id=d.department_id AND e.commission_pct IS NOT NULL
添加分组查询
#查询每个城市的部门个数
select count(*) 个数, city
from departments d,locations l
where d.location_id=l.location_id
GROUP BY l.city
添加排序:有这种每个什么什么的 一般要加分组
#查询每个工种的公工种名和员工个数,并按员工个数降序
select count(*),job_title
from employees e , jobs j
where e.job_id=j.job_id
GROUP BY job_title
ORDER BY count(*)
实现三表连接
# 查询员工名,部门名和所在城市
select last_name, department_name,city
from employees e,departments d, locations l
where e.department_id=d.department_id
and d.location_id=l.location_id
3.1.2非等值连接
#查询员工薪资对应的等级
select salary,grade_level
from employees e,job_grades g
where e.salary BETWEEN lowest_sal AND highest_sal
3.2自连接
自连接就是查询本表中的内容
例如一个员工表中,有领导,也有普通员工(在同一个表中,一个人可能是下级的领导,又是上级的员工)。现在要查询某个员工的领导名(这个人是下级的领导,又是上级的员工)
#查询员工名和上级的名称
select e.employee_id,e.last_name,m.manager_id,m.last_name
from employees e,employees m
where e.manager_id=m.employee_id
----------------99语法-----------------------
3.1 99语法
select 查询列表
from 表1 别名 【连接类型】
join 表2 别名
on 连接条件
【where 筛选条件】
【groupby 分组条件】
【HAVING 筛选条件】
【Order by 排序筛选】
分类:(连接类型)
内连接:inner
外连接:
左外:left 【outer】
右外:right 【outer】
全外:full【outer】
交叉连接:cross
3.2内连接
内连接实现的是多个表的交集
3.2.1等值连接
特点
- 添加排序分组筛选
- inner可以省略
- 实现的功能相同
#案例1.查询员工名、部门名
select last_name,department_name
from employees e JOIN departments d
on e.`department_id`=d.`department_id`
添加筛选
#案例2.查询名字中包含e的员工名和工种名(添加筛选)
select last_name,job_title
from employees e inner JOIN jobs j
on e.job_id =j.job_id
where e.last_name like '%e%'
添加分组
#3.查询部门个数>3的城市名和部门个数,(添加分组+筛选)
#城市对应部门 这里是查询一个城市中的部门个数大于3的城市 最后再把部门个数也查出来
select count(*) 部门个数,city
from locations l
inner join departments d
on l.location_id=d.location_id
GROUP BY city
HAVING COUNT(*)>3
添加排序
#案例4.查询哪个部门的员工个数>3的部门名和员工个数,并按个数降序(添加排序)
select count(*),department_name
from employees e
INNER JOIN departments d
on e.department_id=d.department_id
GROUP BY d.department_name
HAVING COUNT(*)>3
ORDER BY COUNT(*) DESC
添加三表连接
#5.查询员工名、部门名、工种名,并按部门名降序(添加三表连接)
SELECT last_name,department_name,job_title
FROM employees e
INNER JOIN departments d ON e.`department_id`=d.`department_id`
INNER JOIN jobs j ON e.`job_id` = j.`job_id`
3.2.2非等值连接
#查询员工的工资级别
SELECT salary,grade_level
FROM employees e
JOIN job_grades g
ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`;
添加排序
#查询工资级别的个数>20的个数,并且按工资级别降序
SELECT COUNT(*),grade_level
FROM employees e
JOIN job_grades g
ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`
GROUP BY grade_level
HAVING COUNT(*)>20
ORDER BY grade_level DESC;
3.2.3自连接
#查询员工的名字、上级的名字
SELECT e.last_name,m.last_name
FROM employees e
JOIN employees m
ON e.`manager_id`= m.`employee_id`;
3.3外连接
- 外连接的应用场景:用于查询一个表中有,另一个表中没有得记录
- 外连接的查询结果为主表中的所有记录
如果有和他匹配的,则显示匹配信息。如果没有和他匹配的,则显示null。
外连接查询结果=内连接查询结果+主表中有而从表中没有得记录 - 左外连接,left join左边的是主表
右外连接,right join右边的是主表 - 左外右外交换两个表的顺序,可以实现同样效果
3.3.1左外连接
select b.name,bo.*
from beauty b
left join boys bo
on b.boyfriend_id=bo.id
where bo.id is null
部门表里面有,员工表里没有(员工表中部门编号只显示到110)
如果部门表中有,员工表里面也有,那么就展示所有信息
如果部门表里面有,员工表中没有,那么就显示null
最后筛选,其实写员工表中任意一个不可能为null的就可以 比如
员工表中 first_name不可能为null ,就写where e.first_name is null
但是员工表中commission_pct这个有些列就为null,就不能写where e.commission_pct is null
把那些没有全变为了null
#查询哪个部门里面没有员工
select d.*,e.employee_id
from departments d
left OUTER join employees e
on d.department_id=e.department_id
where e.department_id is null
最终筛选的条件需要写成从表的。。。为空
3.3.2右外连接
#查询哪个部门里面没有员工
select d.*,e.employee_id
from employees e
right OUTER join departments d
on d.department_id=e.department_id
where e.department_id is null
3.3.3全外连接
mysql不支持
SELECT <select_list>
FROM A
FULL JOIN B
ON A.key=B.key
3.4交叉连接
就是两个表的笛卡尔乘积
select b.*
from beauty b
cross join boys bo
3.5总结
(四)子查询(内查询)
1、按子查询出现的位置:
- select后面:仅仅支持标量子查询
- from后面:支持表子查询
- where或having后面
标量子查询(单行) √
列子查询 (多行) √
行子查询 - exists后面(相关子查询)
表子查询
2、按结果集的行列数不同:
标量子查询(结果集只有一行一列)
列子查询(结果集只有一列多行)
行子查询(结果集有一行多列)
表子查询(结果集一般为多行多列)
4.1where或having后面
4.1.1标量子查询
非法使用标量子查询的情况
1、结果集有一列/行多行/列
2、where条件不成立
简单标量子查询
#案例1:谁的工资比 Abel 高?
#先要知道able的工资是多少 你才能比较 所以需要两步
select salary
from employees
where last_name='Abel'
select last_name,salary
from employees
where salary>
(select salary
from employees
where last_name='Abel')
需要三个步骤的标量子查询
#案例2:返回job_id与141号员工相同,salary比143号员工多的员工 姓名,job_id 和工资
select last_name,salary
from employees
where employee_id='143'
select last_name,job_id,salary
from employees
where salary>
(
select salary
from employees
where employee_id='143'
)
AND job_id = (
SELECT job_id
FROM employees
WHERE employee_id = 141
)
添加分组 最复杂
#案例4:查询最低工资大于 50号部门最低工资 的部门id 和其最低工资
select min(salary)
from employees
where department_id='50'
#c查询每个部门的最低工资
select min(salary),department_id
from employees
GROUP BY department_id
select department_id,min(salary)
from employees
GROUP BY department_id
HAVING min(salary)>
(
select min(salary)
from employees
where department_id='50'
)
4.1.2列子查询
- any 小于最小
- all 大于最大
any
#返回其它工种中比job_id为‘IT_PROG’工种任一工资低的员工的员工号、姓名、job_id 以及salary
select employee_id,last_name,job_id,salary
from employees
where salary<ANY(select salary
from employees
where job_id='IT_PROG'
)
AND job_id<>'IT_PROG';
ALL
#案例3:返回其它部门中比job_id为‘IT_PROG’部门所有工资都低的员工 的员工号、姓名、job_id 以及salary
SELECT last_name,employee_id,job_id,salary
FROM employees
WHERE salary<ALL(
SELECT DISTINCT salary
FROM employees
WHERE job_id = 'IT_PROG'
) AND job_id<>'IT_PROG';
#或
SELECT last_name,employee_id,job_id,salary
FROM employees
WHERE salary<(
SELECT MIN( salary)
FROM employees
WHERE job_id = 'IT_PROG'
) AND job_id<>'IT_PROG';
4.1.3行子查询
结果集是一行多列
#案例:查询员工编号最小并且工资最高的员工信息
select min(employee_id)
from employees
select min(salary)
FROM employees
#正常人的写法
SELECT
*
FROM
employees
WHERE
employee_id = ( SELECT min( employee_id ) FROM employees )
AND salary = ( SELECT min( salary ) FROM employees )
#行子查询的写法
SELECT *
FROM employees
WHERE (employee_id,salary)=(
SELECT MIN(employee_id),MAX(salary)
FROM employees
);
4.2select后的子查询
子查询语句放在select
只支持标量子查询
#查询每个部门的员工个数 有的部门编号中没有员工,也要查出来没有员工的部门,并且显示员工个数为0
#按照分组查 找不到个数为0的
select count(*),d.department_id
from employees e
left join departments d
on d.department_id=e.department_id
group by d.department_id
#使用select后子查询进行查询
select d.*,(
select count(*)
from employees e
where e.department_id=d.department_id
)
from departments d
4.3from后的子查询
#查询每个部门的平均工资的工资等级
SELECT
ag_dep.*,
grade_level
FROM
( SELECT AVG( salary ) ag, department_id FROM employees GROUP BY department_id ) ag_dep
INNER JOIN job_grades g ON ag_dep.ag BETWEEN lowest_sal
AND highest_sal
先查询每个部门的平均工资,将其作为一个表,在连接等级表,来筛选工资等级
4.3exist后的子查询
select exists(查询语句)
返回1或者0
#案例1:查询有员工的部门名
#in
SELECT department_name
FROM departments d
WHERE d.`department_id` IN(
SELECT department_id
FROM employees
)
(五)分页查询
select 字段|表达式,…
from 表
【where 条件】
【group by 分组字段】
【having 条件】
【order by 排序的字段】
limit 【起始的条目索引,】条目数;
(page-1)*size,size
#案例3:有奖金的员工信息,并且工资较高的11-15名显示出来
select *
from employees
where commission_pct is not null
order by salary DESC
LIMIT 10,5
#5是显示的条目数 这里显示5条
(六)联合查询
应用场景:要查询的结果来自于多个表,且多个表没有直接的连接关系,但查询的信息一致
特点:
1、要求多条查询语句的查询列数一致
2、要求多条查询语句的查询的每一列的类型和顺序最好一致
3、union关键字默认去重,使用union all可以包含重复项