MySQL单表查询:
目的:在MySQL管理软件中,可以通过SQL语句中的DQL语言来实现数据的
分类:
简单查询:如所有记录
通过条件查询:如某条记录
查询序列:如看看名次
限制查询记录数:如只看三条
使用集合函数查询:如看总价
分组查询:如查询结果分类
使用正则表达式查询:模糊查询
表结构:
结构语句:
mysql> CREATE TABLE company.employee5(
id int primary key AUTO_INCREMENT not null,
name varchar(30) not null,
sex enum('male','female') default 'male' not null,
hire_date date not null,
post varchar(50) not null,
job_description varchar(100),
salary double(15,2) not null,
office int,
dep_id int
);
插入数据:
一、简单查询:
查看所以信息:SELECT * FROM employee5;
查看员工姓名,工资,部门:SELECT name, salary, dep_id FROM employee5;
看看有哪些部门:SELECT post FROM employee5;
(存在重复字段)
如何解决:SELECT DISTINCT post FROM employee5;
(SELECT DISTINCT post FROM employee5;
DISTINCT 有区别的)
看看年薪:
SELECT name, salary, salary14 FROM employee5;
美化输出:
SELECT name, salary, salary14 AS Annual_salary FROM employee5;
(as 别名)
SELECT name, salary, salary14 Annual_salary FROM employee5;
(as可以省略)
美化输出2:
CONCAT( ) 函数用于连接字符串,引号标识拼接的符号
select name,salary,salary14 from employee5;
select concat(name,salary,salary14) from employee5;
select name,'annual salary:',salary14 from employee5;
select concat(name,'annual salary:',salary14) from employee5;
SELECT CONCAT(name, ' annual salary: ', salary14) AS Annual_salary FROM employee5;
二、单条件查询where
查询hr部门的员工姓名:
SELECT name,post
FROM employee5
WHERE post='hr';
多条件查询AND/OR:查询hr部门的员工,并且工资大于1000
SELECT name,salary
FROM employee5
WHERE post='hr' AND salary>10000;
查询所有部门的员工,并且工资是4000或者5000的员工:
SELECT name, salary FROM employee5
WHERE salary=4000 OR salary=5000
关键字BETWEEN AND 在什么之间:查一查薪资在5000到15000:
SELECT name,salary FROM employee5
WHERE salary BETWEEN 5000 AND 15000;
使用NOT查一查不再5000到15000之间的:
SELECT name,salary FROM employee5
WHERE salary NOT BETWEEN 5000 AND 15000;
关键字IN集合查询:工资可能是4000,也可能是5000,还有可能是9000,怎么查
OR可以组合多条件,效率如何?
SELECT name, salary FROM employee5
WHERE salary=4000 OR salary=5000 OR salary=6000 OR salary=9000 ;
优化:
是什么什么
SELECT name, salary FROM employee5
WHERE salary IN (4000,5000,6000,9000) ;
不是什么什么
SELECT name, salary FROM employee
WHERE salary NOT IN (4000,5000,6000,9000) ;
关键字IS NULL:没有岗位描述的
空
SELECT name,job_description FROM employee5
WHERE job_description IS NULL;
非空
SELECT name,job_description FROM employee5
WHERE job_description IS NOT NULL;
错误示范,空格''
SELECT name,job_description FROM employee5
WHERE job_description='';
关键字LIKE模糊查询:
SELECT * FROM employee5
WHERE name LIKE 'al%';
(通配符’%’代表多个任意字符,注意不是shell的"*"星号。mysql使用"%")
SELECT * FROM employee5
WHERE name LIKE 'al___';
(注意不是shell的“?”问号。mysql使用""下划线,通配符’’代表1个任意字符)
三、查询排序order by
按单列排序:
工资从低到高,怎么查(升序):
SELECT * FROM employee5 ORDER BY salary;
SELECT name, salary FROM employee5 ORDER BY salary ASC;
(默认就是升序,所以ASC可以省略)
工资从高到低,怎么查(将序):
SELECT name, salary FROM employee5 ORDER BY salary DESC;
按多列排序:在满足第一列条件下,再进行第二列的排序。
SELECT * FROM employee5
ORDER BY hire_date DESC,
salary DESC;
先按最近的入职时间,再按低薪水排序
同一个职位,谁的薪资高。
四、限制查询的记录数limit
SELECT * FROM employee5 ORDER BY salary DESC
LIMIT 5; (默认初始值为0)
SELECT * FROM employee5 ORDER BY salary DESC
LIMIT 0,5; (逗号步长)
SELECT * FROM employee5 ORDER BY salary DESC
LIMIT 3,5;(从第三条开始,共显示5条)
五、使用集合函数查询MAX()
SELECT COUNT() FROM employee5;(共多少员工,count()计数)
SELECT COUNT() FROM employee5 WHERE dep_id=101;(101部门多少人)
SELECT MAX(salary) FROM employee5;(谁的工资最高)
SELECT MIN(salary) FROM employee5;(谁的工资最低)
SELECT AVG(salary) FROM employee5;(平均薪资是多少)
SELECT SUM(salary) FROM employee5;(全公司薪资总和是多少)
SELECT SUM(salary) FROM employee5 WHERE dep_id=101;(101部门薪资总和多少)
select group_concat(name) from employee5 ;(将员工名称集中起来)
(注意:
concat显示的是独立字段
group_concat显示结果是一整条记录
)
六、分组查询GROUP BY
SELECT dep_id,GROUP_CONCAT(name) FROM employee5 GROUP BY dep_id;
(每个部门的人员名单)
SELECT dep_id FROM employee5 GROUP BY dep_id;
(请思考group by 的效果)
select dep_id,SUM(salary) from employee5 group by dep_id;
(每个部门的工资总和)
select dep_id,AVG(salary) from employee5 group by dep_id;
(每个部门的工资平均值)
七、使用正则表达式查询REGEXP
SELECT * FROM employee5 WHERE name REGEXP '^ali';
SELECT * FROM employee5 WHERE name REGEXP 'yun$';
(查询yun结尾的记录)
SELECT * FROM employee5 WHERE name REGEXP 'm{2}';
(查询m出现过2次的记录)
总结:对字符串匹配的方式
SELECT 查询操作
MySQL多表查询:
前言:
如何根据部门总表中,查询分支表信息
一、分类
- 多表连接查询,复合条件连接查询
- 子查询 ,根据查询结果查询。
准备员工信息表
create table info(
name char(50),
age int,
dep_num int,
level_num int);
desc info;
insert into info values
('zhangsan',23,101,1),
('lisi',25,102,2),
('wangwu',30,102,3),
('zhaosi',30,103,4),
('sunba',35,NULL,NULL);
select * from info;
准备部门信息表:
create table department(
dep_num int,
dep_name varchar(50),
dep_des varchar(100));
insert into department values
(101,'hr','recruit,training'),
(102,'tec','system,network,service'),
(103,'exp','C++,python,php'),
(104,'admin','administrator');
desc department;
select * from department;
二、多表的连接查询
交叉连接: 生成笛卡尔积,它不使用任何匹配条件
特点:全部组合(A表5行,B表7行,最后5*7=35行)
语法:生成笛卡尔积,它不使用任何匹配条件
touch {a..c}{1..3}
示范:select info.name,info.age,info.dep_num,department.dep_name from info,department;
mysql> select info.name,info.age,info.dep_num,department.dep_name from info,department;
+----------+------+---------+----------+
| name | age | dep_num | dep_name |
+----------+------+---------+----------+
| zhangsan | 23 | 101 | hr |
| zhangsan | 23 | 101 | tec |
| zhangsan | 23 | 101 | exp |
| zhangsan | 23 | 101 | admin |
| lisi | 25 | 102 | hr |
| lisi | 25 | 102 | tec |
| lisi | 25 | 102 | exp |
| lisi | 25 | 102 | admin |
| wangwu | 30 | 102 | hr |
| wangwu | 30 | 102 | tec |
| wangwu | 30 | 102 | exp |
| wangwu | 30 | 102 | admin |
| zhaosi | 30 | 103 | hr |
| zhaosi | 30 | 103 | tec |
| zhaosi | 30 | 103 | exp |
| zhaosi | 30 | 103 | admin |
| qianqi | 30 | 104 | hr |
| qianqi | 30 | 104 | tec |
| qianqi | 30 | 104 | exp |
| qianqi | 30 | 104 | admin |
| sunba | 35 | NULL | hr |
| sunba | 35 | NULL | tec |
| sunba | 35 | NULL | exp |
| sunba | 35 | NULL | admin |
+----------+------+---------+----------+
24 rows in set (0.00 sec)
内连接:只连接匹配的行
特点:两列相同时,才会显示
需求:显示员工的部门信息
语法:SELECT 字段列表
FROM 表1 , 表2
WHERE 表1.字段 = 表2.字段;
示例:
select info.name,info.age,info.dep_num,department.dep_name from info,department where info.dep_num = department.dep_num;
请思考:孙八去哪了。
外链接:
特点:两列相同时显示,并,已左/右表为主。
语法:A表 left join B表 on 条件是
外连接(左连接 left join on): 会显示左边表内所有的值,不论在右边表内匹不匹配
需求:找出所有员工及所属的部门,包括没有部门的员工
查看所有员工的部门信息。
示例:
select info.name,info.age,info.dep_num,department.dep_name from info left join department on info.dep_num = department.dep_num;
请思考:是否显示了所有部门。
如果,希望显示所有部门中的员工,该如何查询?
外连接(右连接right join on): 会显示右边表内所有的值,不论在左边表内匹不匹配
需求:显示所有的部门的员工信息。
示范:
select info.name,info.age,info.dep_num,department.dep_name from info right join department on info.dep_num = department.dep_num;
需求2:找出公司所有部门中年龄大于25岁的员工
示例:
select info.name,info.age,info.dep_num,department.dep_name
from
info right join department
on
info.dep_num = department.dep_num
AND age > 25;
需求3:找出公司所有部门中的员工,对他们的年龄排序
示例:
select info.name,info.age,info.dep_num,department.dep_name
from
info right join department
on
info.dep_num = department.dep_num
ORDER BY
age
ASC;
三、子查询
简介:
子查询是指:父查询 需要 依赖 子查询的结果。
子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字
还可以包含比较运算符:= 、 !=、> 、<等
-
带IN关键字的子查询(范围)
需求:查询员工年龄大于等于35岁的部门(查询老龄化的部门)
示例:
select dep_num,dep_name
from
department
where
dep_num
in
(select distinct dep_num from info where age >=35);
- 带EXISTS关键字的子查询(返回值)
简介:
EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录,而是返回一个真假值。
Ture或False,当返回Ture时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询
需求:如果部门101存在(返回为真),查询所有员工信息。
示例:
true:无结果
select * from info
where
exists
(select * from department where dep_num=102);
false:无结果
select * from info where exists (select * from department where dep_num=105);