目录
- DISTINCT:去重,执行顺序是在having过滤后执行去重
- 外连接 - LEFT JOIN (左连接) :获取左表所有记录,即右表没有对应匹配的记录
- 外连接 - RIGHT JOIN(右连接):获取右表所有记录,即左表没有对应匹配的记录
- INNER JOIN(内连接 或 等值连接):获取两个表中字段匹配关系的记录
单表查询
- 语法
SELECT 字段1,字段2... FROM 表名
WHERE 条件
GROUP BY field
HAVING 筛选
ORDER BY field
LIMIT 限制条数
- 关键字的执行优先级
- from :找到表
- where:拿到约束条件,去表中取记录
- group by:取出记录进行分组,若没有group by关键字,则整体作为一组
- having:将分组结果进行过滤
- select:查找
- distinct:去重
- order by:将结果按条件进行排序
- limit:限制结果的显示条数
- 简单查询
SELECT id,name,sex,age,hire_date,post,post_comment,salary,office,depart_id
FROM employee;
SELECT * FROM employee;
SELECT name,salary FROM employee;
- WHERE语句
SELECT field1, field2,...fieldN
FROM table_name1, table_name2...
[WHERE condition1 [AND [OR]] condition2.....
例如: select * from tb where 字段名 = ‘指定名字’
where 约束:
- 比较运算符,如下图:
- between 1 and 10 ------1-10之间
- in(8,,3,4) -------是8或3或4
- and,or,not ----------逻辑运算符
-
%,_用法:
‘%a’ : 以a结尾的数据
'a%' : 以a开头的数据
'%a%' : 含a的数据
'_a_' : 三位且中间字母为a的
'_a' : 两位且结尾字母是a的
'a_' : 两位且开头字母是a的
-
WHERE LIKE:获取类正则的使用效果
-
SELECT field1, field2,...fieldN FROM table_name WHERE field1 LIKE condition1 [AND [OR]] filed2 = 'somevalue'
例:SELECT * from runoob_tbl WHERE runoob_author LIKE '%COM';
- 可以在where子句中指定任何条件。
- 可以使用like子句代替等号=。
- like通常与%一同使用,类似于一个元字符的搜索。
- 可以使用 and 或者 or 指定一个或多个条件。
- 可以在 delete 或 update 命令中使用 where…like 子句来指定条件
- ORDER BY 查询后排序返回
SELECT field1, field2,...fieldN table_name1, table_name2...
ORDER BY field1, [field2...] [ASC [DESC]]
例:SELECT * from runoob_tbl ORDER BY submission_date ASC;
- 你可以使用任何字段来作为排序的条件,从而返回排序后的查询结果。
- 你可以设定多个字段来排序。
- 你可以使用 ASC(升序) 或 DESC(降序) 来设置查询结果是按升序或降序排列。 默认情况下,它是按升序排列。
- 你可以添加 WHERE...LIKE 子句来设置条件。
- GROUP BY :根据一个列或多个列进行分组
SELECT column_name, function(column_name)
FROM table_name
WHERE column_name operator value
GROUP BY column_name;
例:SELECT 字段1, SUM(字段2) as 新字段2 FROM table1 GROUP BY 字段1 WITH ROLLUP;
注:
#设置sql_mode为only_full_group_by,意味着以后但凡分组,只能取到分组的依据
mysql> set global sql_mode="strict_trans_tables,only_full_group_by";
#分组之后的聚合操作:
select post,max(salary) from emp group by post; #每个部门的最高工资
select post,min(salary) from emp group by post; #每个部门的最低工资
select post,avg(salary) from emp group by post; #每个部门的平均工资
select post,sum(salary) from emp group by post; #每个部门的工资综合
select post,count(id) from emp group by post; #每个部门的员工数
#group_concat(分组之后用,取出字段,或者对指定字段执行拼接操作)
select post,group_concat(name) from emp group by post;
select post,group_concat(name,"_SB") from emp group by post;
select post,group_concat(name,": ",salary) from emp group by post;
select post,group_concat(salary) from emp group by post;
# 补充concat(不分组时用,取出字段并对指定字段进行拼接操作。用as将字段起别名)
select name as 姓名,salary as 薪资 from emp;
select concat("NAME: ",name) as 姓名,concat("SAL: ",salary) as 薪资 from emp;
# concat_ws(不分组时使用,多次使用相同拼接符缩写)
select concat_ws(":",name,age,sex,post)as info from emp;
'''
concat_ws("分隔符",字段名1,字段名2,...) as 别名
数据结果:
name1:14:female:operation
name2:15:female:operation
.......
'''
# 补充as语法(起别名)
mysql> select emp.id,emp.name from emp as t1; # 报错
mysql> select t1.id,t1.name from emp as t1;
# 查询四则运算(加减乘除)
select name,salary*12 as annual_salary from emp;
'''可以省略as 上下两句结果相同'''
select name,salary*12 annual_salary from emp;
- HAVING :在分组后的过滤
having & where:
- !!!执行优先级从高到低:where > group by > having
- 1. Where 发生在分组group by之前,因而Where中可以有任意字段,但是绝对不能使用聚合函数。
- 2. Having发生在分组group by之后,因而Having中可以使用分组的字段,无法直接取到其他字段,可以使用聚合函数
例:select post,group_concat(name) from emp group by post having avg(salary) > 10000;
- DISTINCT:去重,执行顺序是在having过滤后执行去重
select distinct post,avg(salary) from emp
where age >= 30
group by post
having avg(salary) > 10000;
- LIMIT :限制查询的记录数
示例:(分页显示)
SELECT * FROM employee ORDER BY salary DESC LIMIT 3;
#默认初始位置为0 (0,3]
SELECT * FROM employee ORDER BY salary DESC LIMIT 0,5;
#从第0开始,即先查询出第1条,然后包含这一条在内往后查5条((0,5],取后不取前)
SELECT * FROM employee ORDER BY salary DESC LIMIT 5,5;
#从第5开始,即先查询出第6条,然后包含这一条在内往后查5条
- REGEXP(正则表达式) 查询
SELECT * FROM employee WHERE name REGEXP '^ale';
SELECT * FROM employee WHERE name REGEXP 'on$';
SELECT * FROM employee WHERE name REGEXP 'm{2}';
小结:对字符串匹配的方式
WHERE name = 'name';
WHERE name LIKE 'yua%';
WHERE name REGEXP 'on$';
- 聚合函数:聚合的是组的内容,若是没有分组,则默认一组
示例:
SELECT COUNT(*) FROM employee;
SELECT COUNT(*) FROM employee WHERE depart_id=1;
SELECT MAX(salary) FROM employee;
SELECT MIN(salary) FROM employee;
SELECT AVG(salary) FROM employee;
SELECT SUM(salary) FROM employee;
SELECT SUM(salary) FROM employee WHERE depart_id=3;
多表查询
- 表的外连接语法
SELECT 字段列表
FROM 表1 INNER|LEFT|RIGHT JOIN 表2
ON 表1.字段 = 表2.字段;
- 外连接 - LEFT JOIN (左连接) :获取左表所有记录,即右表没有对应匹配的记录
- 外连接 - RIGHT JOIN(右连接):获取右表所有记录,即左表没有对应匹配的记录
- INNER JOIN(内连接 或 等值连接):获取两个表中字段匹配关系的记录
- FULL JOIN(全外连接):显示左右俩表全部记录
注:
- mysql不支持全外连接,但是mysql可以间接实现全外连接
- 注意 union与union all的区别:union会去掉相同的纪录
select * from employee left join department on employee.dep_id = department.id
union
select * from employee right join department on employee.dep_id = department.id;
- 交叉连接:不使用任何匹配条件。生产笛卡尔积
select * from employee,department;
- 符合条件的连接查询
- 内连接方式查询,并设置where筛选
select employee.name,department.name from employee inner join department
on employee.dep_id = department.id
where age > 25;
- 内连接方式查询,并设置字段排序方式显示
select employee.id,employee.name,employee.age,department.name from employee,department
where employee.dep_id = department.id
and age > 25
order by age asc;
- 子查询
#1:子查询是将一个查询语句嵌套在另一个查询语句中。
#2:内层查询语句的查询结果,可以为外层查询语句提供查询条件。
#3:子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字
#4:还可以包含比较运算符:= 、 !=、> 、<等
-
带IN关键字的子查询
#查询平均年龄在25岁以上的部门名 select id,name from department where id in (select dep_id from employee group by dep_id having avg(age) > 25); #查看技术部员工姓名 select name from employee where dep_id in (select id from department where name='技术'); #查看不足1人的部门名(子查询得到的是有人的部门id) select name from department where id not in (select distinct dep_id from employee);
-
带比较运算符的子查询
#比较运算符:=、!=、>、>=、<、<=、<> #查询大于所有人平均年龄的员工名与年龄 mysql> select name,age from emp where age > (select avg(age) from emp); +---------+------+ | name | age | +---------+------+ | name1 | 48 | | name2 | 38 | +---------+------+ 2 rows in set (0.00 sec) #查询大于部门内平均年龄的员工名、年龄 select t1.name,t1.age from emp t1 inner join (select dep_id,avg(age) avg_age from emp group by dep_id) t2 on t1.dep_id = t2.dep_id where t1.age > t2.avg_age;
-
带EXISTS关键字的子查询
#比较运算符:=、!=、>、>=、<、<=、<> #查询大于所有人平均年龄的员工名与年龄 mysql> select name,age from emp where age > (select avg(age) from emp); +---------+------+ | name | age | +---------+------+ | name1 | 48 | | name2 | 38 | +---------+------+ 2 rows in set (0.00 sec) #查询大于部门内平均年龄的员工名、年龄 select t1.name,t1.age from emp t1 inner join (select dep_id,avg(age) avg_age from emp group by dep_id) t2 on t1.dep_id = t2.dep_id where t1.age > t2.avg_age;