Author:行癫
GitHub:https://github.com/blackmed/mysql.git
目录:
●数据库查询
● 多表查询
单表查询
简单查询
通过条件查询
查询排序
限制查询记录数
使用集合函数查询
分组查询
使用正则表达式查询
测试表:company.employee5
雇员编号 id int
雇员姓名 name varchar(30)
雇员性别 sex enum
雇用时期 hire_date date
职位 post varchar(50)
职位描述 job_description varchar(100)
薪水 salary double(15,2)
办公室 office int
部门编号 dep_id int
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
);
mysql> insert into company.employee5(name,sex,hire_date,post,job_description,salary,office,dep_id) values
('jack','male','20180202','instructor','teach',5000,501,100),
('tom','male','20180203','instructor','teach',5500,501,100),
('robin','male','20180202','instructor','teach',8000,501,100),
('alice','female','20180202','instructor','teach',7200,501,100),
('','male','20180202','hr','hrcc',600,502,101),
('harry','male','20180202','hr',NULL,6000,502,101),
('emma','female','20180206','sale','salecc',20000,503,102),
('christine','female','20180205','sale','salecc',2200,503,102),
('zhuzhu','male','20180205','sale',NULL,2200,503,102),
('gougou','male','20180205','sale','',2200,503,102);
mysql> select 字段名称,字段名称2 from 表名 条件
简单查询:
mysql> select * from employee5;
mysql> select name, salary, dep_id from employee5 where id <=5;
避免重复DISTINCT
SELECT post FROM employee5;
SELECT distinct post FROM employee5;
注:不能部分使用DISTINCT,通常仅用于某一字段。
通过四则运算查询
SELECT name, salary, salary*14 FROM employee5;
SELECT name, salary, salary*14 AS Annual_salary FROM employee5;
SELECT name, salary, salary*14 Annual_salary FROM employee5;
定义显示格式
CONCAT() 函数用于连接字符串
SELECT concat(name, 's annual salary: ', salary*14) AS Annual_salary FROM employee5;
单条件查询
SELECT name,post FROM employee5 WHERE post='hr';
多条件查询
SELECT name,salary FROM employee5 WHERE post='hr' AND salary>10000;
select * from employee5 where salary>5000 and salary<10000 or dep_id=102;
关键字BETWEEN AND between and
SELECT name,salary FROM employee5 WHERE salary BETWEEN 5000 AND 15000;
SELECT name,salary FROM employee5 WHERE salary NOT BETWEEN 5000 AND 15000;
关键字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='';
NULL说明:
1、等价于没有任何值、是未知数。
2、NULL与0、空字符串、空格都不同,NULL没有分配存储空间。
3、对空值做加、减、乘、除等运算操作,结果仍为空。
4、比较时使用关键字用“is null”和“is not null”。
5、排序时比其他数据都小(索引默认是降序排列,小→大),所以NULL值总是排在最前。
关键字IN集合查询
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) ;
关键字LIKE模糊查询
通配符’% ’:所有字符
SELECT * FROM employee5 WHERE name LIKE 'al%';
通配符’_’ 一个字符
SELECT * FROM employee5 WHERE name LIKE 'al___';
排序查询
mysql> select china from t1 order by china;
mysql> select china from t1 order by china desc;
mysql> select china from t1 order by china desc limit 3; 控制显示前3行。
mysql> select china from t1 order by china desc limit 1,3; 从序号1开始显示三行的内容。
注:
ascending 美音 /ə'sɛndɪŋ/ 升序
descending 美音 /dɪ'sɛndɪŋ/ 降序
按多列排序:
入职时间相同的人薪水不同
SELECT * FROM employee5 ORDER BY hire_date DESC,salary ASC;
限制查询的记录数
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; //从第4条开始,共显示5条
使用集合函数查询
count 可以查看共有多少条记录
select count(*) from employee5;
select count( name) from employee5;
select max(salary) from employee5; //部门薪资最高
select min(salary) from employee5;
select avg(salary) from employee5;
sale这个部门的总工资:
select concat("Total Department Wages:",sum(salary)) from employee5 where post='sale';
打印薪水最高的这个人的详细信息:
select * from employee5 where salary = (select max(salary) from employee5);
分组查询:
GROUP BY和GROUP_CONCAT()函数一起使用
部门ID相同,就把名字拼到一起:
SELECT dep_id,GROUP_CONCAT(name) FROM employee5 GROUP BY dep_id;
SELECT dep_id,GROUP_CONCAT(name) as emp_members FROM employee5 GROUP BY dep_id;
GROUP BY和集合函数一起使用
部门最高薪资
SELECT post,max(salary) FROM employee5 GROUP BY post;
+------------+-------------+
| post | max(salary) |
+------------+-------------+
| hr | 6000.00 |
| instructor | 8000.00 |
| sale | 20000.00 |
+------------+-------------+
3 rows in set (0.07 sec)
正则查询
SELECT * FROM employee5 WHERE name REGEXP '^ali';
SELECT * FROM employee5 WHERE name REGEXP 'yun$';
小结:对字符串匹配的方式
WHERE name = 'tom';
WHERE name LIKE 'to%'; _ %
左右内链接
多表连接查询
复合条件连接查询
一、准备两张测试表
表company.employee6
mysql> create table employee6(
emp_id int auto_increment primary key not null,
emp_name varchar(50),
age int,
dept_id int);
mysql> desc employee6;
mysql> insert into employee6(emp_name,age,dept_id) values
('',19,200),
('tom',26,201),
('jack',30,201),
('alice',24,202),
('robin',40,200),
('xingdian',16,200),
('natasha',28,204);
mysql> select * from employee6;
表company.department6
mysql> create table department6(
dept_id int,
dept_name varchar(100)
);
mysql> desc department6;
mysql> insert into department6 values
(200,'hr'),
(201,'it'),
(202,'sale'),
(203,'fd');
mysql> select * from department6;
注:
Financial department:财务部门 fd
二、多表的连接查询
交叉连接: 生成笛卡尔积,它不使用任何匹配条件
交叉联接返回左表中的所有行,左表中的每一行与右表中的所有行组合
内连接: 只连接匹配的行
外连接
左连接: 会显示左边表内所有的值,不论在右边表内匹不匹配
右连接: 会显示右边表内所有的值,不论在左边表内匹不匹配
全外连接: 包含左、右两个表的全部行
=================交叉连接=======================
>select employee6.emp_name,employee6.age,employee6.dept_id,department6.dept_name from employee6,department6;
=================内连接=======================
只找出有部门的员工 (部门表中没有natasha所在的部门)
>select employee6.emp_name,employee6.age,employee6.dept_id,department6.dept_name from employee6,department6 where employee6.dept_id=department6.dept_id;
>select employee6.emp_name,department6.dept_name from employee6 inner join department6 on employee6.dept_id=department6.dept_id;
外连接语法:
SELECT 字段列表
FROM 表1 LEFT|RIGHT JOIN 表2
ON 表1.字段 = 表2.字段;
先用谁谁就是左。
=================外连接(左连接 left join)=======================
mysql> select emp_id,emp_name,dept_name from employee6 left join department6 on employee6.dept_id = department6.dept_id;
找出所有员工及所属的部门,包括没有部门的员工
=================外连接(右连接right join)=======================
mysql> select emp_id,emp_name,dept_name from employee6 right join department6 on employee6.dept_id = department6.dept_id;
找出所有部门包含的员工,包括空部门
=================全外连接=======================
mysql> select * from employee6 full join department6;
+--------+----------+---------+---------+-----------+
| emp_id | emp_name | dept_id | dept_id | dept_name |
+--------+----------+---------+---------+-----------+
| 1 | | 200 | 200 | hr |
| 1 | | 200 | 201 | it |
| 1 | | 200 | 202 | sale |
| 1 | | 200 | 203 | fd |
| 2 | tom | 201 | 200 | hr |
| 2 | tom | 201 | 201 | it |
| 2 | tom | 201 | 202 | sale |
| 2 | tom | 201 | 203 | fd |
| 3 | jack | 201 | 200 | hr |
| 3 | jack | 201 | 201 | it |
| 3 | jack | 201 | 202 | sale |
| 3 | jack | 201 | 203 | fd |
| 4 | alice | 202 | 200 | hr |
| 4 | alice | 202 | 201 | it |
| 4 | alice | 202 | 202 | sale |
| 4 | alice | 202 | 203 | fd |
| 5 | robin | 200 | 200 | hr |
| 5 | robin | 200 | 201 | it |
| 5 | robin | 200 | 202 | sale |
| 5 | robin | 200 | 203 | fd |
| 6 | natasha | 204 | 200 | hr |
| 6 | natasha | 204 | 201 | it |
| 6 | natasha | 204 | 202 | sale |
| 6 | natasha | 204 | 203 | fd |
+--------+----------+---------+---------+-----------+
24 rows in set (0.00 sec)
三、复合条件连接查询
示例1:以内连接的方式查询employee6和department6表,并且employee6表中的age字段值必须大于25
找出公司所有部门中年龄大于25岁的员工
示例2:以内连接的方式查询employee6和department6表,并且以age字段的升序方式显示
四、子查询
子查询是将一个查询语句嵌套在另一个查询语句中。
内层查询语句的查询结果,可以为外层查询语句提供查询条件。
子查询中可以包含:IN、NOT IN等关键字
还可以包含比较运算符:= 、 !=、> 、<等
1. 带IN关键字的子查询
查询employee表,但dept_id必须在department表中出现过
2. 带比较运算符的子查询
=、!=、>、>=、<、<=、<>
查询年龄大于等于25岁员工所在部门(查询老龄化的部门)