Java打怪之路-----MySQL之查询

(一)普通查询

1.1基础查询

  1. 查询语句(包括查询常量、表达式、函数):
    select 内容 from 表名
    其中内容可以是*,可以是1+1,可以是10,可以是一个函数
  2. 起别名和去重
    select 内容 as 内容别名 from 表名
    如果需要去掉重复
    SELECT DISTINCT 内容as 内容别名from 表名;
  3. 字符串拼接(解决拼接过程中值为null):使用Concat()函数
    select concat(last_name,first_name) as 姓名 FROM employees;
    在字符串拼接时,如果字符串中值有空值,则整个查询为空值,所以使用IFNULL来进行筛选
select IFNULL(commission_pct,0)  FROM employees;

第一个参数表示哪个列,第二个参数表示如果是null 则赋值为某个值

1.2条件查询

  1. 条件查询语句select
    查询内容 from 表名 where
  2. 逻辑运算符与条件表达式
    < >= <= = != <>
    and(&&):两个条件如果同时成立,结果为true,否则为false
    or(||):两个条件只要有一个成立,结果为true,否则为false
    not(!):如果条件成立,则not后为false,否则为true

1.3模糊查询

1.3.1 LIKE

  1. 查询语句
    select 内容 from 表名 where 内容like (一般使用通配符)
  2. 通配符
    %表示匹配任意多个字符,包含0个字符
    _表示匹配任意单个字符。
  3. 查询员工名中包含字符a的员工信息
select * from empleyees where last_name LIKE '%a%'
  1. 查询员工名中第三个字符为e,第五个字符为a的员工名和工资
select last_name,salary from empleyees  where Last_name LIKE '__e_a%'
  1. 转义字符
    查询第二个字符是下划线的员工信息。
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

  1. 查询语句
    select 内容 from 表名 where BETWEEN A ADN B
  2. 通配符
    A与B值不能调换

1.3.2 IN

  1. 查询某字段的值是否属于某一列。主要是来替换or。in列表的值类型必须一致
  2. 查询语句:查训工作编号为IT_PROT’,'AD_VP’两个的员工姓名与工作编号
    select 内容 last_name ,job_id from where job_id IN(‘IT_PROT’,‘AD_VP’);
  3. 不支持通配符

1.3.3 IS_NULL与安全等于

  1. =、<> 无法判断null值,使用is_null来进行判断
    SELECT last_name,commission_pct FROM employees where ISNULL(commission_pct)
  2. 安全等于<=>:判断是否等于,可以查到null值,也可以查看普通数值。

1.4排序查询

  1. 查询语句:
    select 查询列表 from 表名 [where] order by 排序列表[dec|asc]
  2. asc升序 默认是升序。这个语句一般放在最后面,除了limit语句
  3. 按照条件查询排序
    查询部门编号>=90的员工信息,并按员工编号降序
    SELECT *FROM employees WHERE department_id>=90 ORDER BY employee_id DESC;
  4. 按照表达式排序
    查询员工信息 按年薪降序
    select * ,salary12(1+IFNULL(commission_pct,0)) as 年薪 FROM employees ORDER BY salary12(1+IFNULL(commission_pct,0)) DESC;
  5. 按照别名排序
    查询员工信息 按年薪降序
    select * ,salary12(1+IFNULL(commission_pct,0)) as 年薪 FROM employees ORDER BY 年薪 DESC;
  6. 按照函排序
    查询员工名,并且按名字的长度降序
    SELECT LENGTH(last_name),last_name FROM employees ORDER BY LENGTH(last_name) DESC;
  7. 按照多个字段排序
    查询员工信息,要求先按工资降序,再按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

(三)连接查询

连接查询的分类
按功能分类:

  1. 内连接
    等值连接
    非等值连接
    自连接
  2. 外连接
    左外连接
    右外连接
    全外连接
  3. 交叉连接

----------------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等值连接

特点

  1. 添加排序分组筛选
  2. inner可以省略
  3. 实现的功能相同
#案例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外连接

  1. 外连接的应用场景:用于查询一个表中有,另一个表中没有得记录
  2. 外连接的查询结果为主表中的所有记录
    如果有和他匹配的,则显示匹配信息。如果没有和他匹配的,则显示null。
    外连接查询结果=内连接查询结果+主表中有而从表中没有得记录
  3. 左外连接,left join左边的是主表
    右外连接,right join右边的是主表
  4. 左外右外交换两个表的顺序,可以实现同样效果

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、按子查询出现的位置:

  1. select后面:仅仅支持标量子查询
  2. from后面:支持表子查询
  3. where或having后面
    标量子查询(单行) √
    列子查询 (多行) √
    行子查询
  4. 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列子查询

在这里插入图片描述

  1. any 小于最小
  2. 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可以包含重复项

猜你喜欢

转载自blog.csdn.net/weixin_44020747/article/details/118243498