MySQL 之 单表查询
Posted 裙下的小香蕉
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL 之 单表查询相关的知识,希望对你有一定的参考价值。
一.简单查询
-- 创建表
DROP TABLE IF EXISTS `person`;
CREATE TABLE `person` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`age` tinyint(4) DEFAULT \'0\',
`sex` enum(\'男\',\'女\',\'人妖\') NOT NULL DEFAULT \'人妖\',
`salary` decimal(10,2) NOT NULL DEFAULT \'250.00\',
`hire_date` date NOT NULL,
`dept_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;
-- 创建数据
-- 教学部
INSERT INTO `person` VALUES (\'1\', \'alex\', \'28\', \'人妖\', \'53000.00\', \'2010-06-21\', \'1\');
INSERT INTO `person` VALUES (\'2\', \'wupeiqi\', \'23\', \'男\', \'8000.00\', \'2011-02-21\', \'1\');
INSERT INTO `person` VALUES (\'3\', \'egon\', \'30\', \'男\', \'6500.00\', \'2015-06-21\', \'1\');
INSERT INTO `person` VALUES (\'4\', \'jingnvshen\', \'18\', \'女\', \'6680.00\', \'2014-06-21\', \'1\');
-- 销售部
INSERT INTO `person` VALUES (\'5\', \'歪歪\', \'20\', \'女\', \'3000.00\', \'2015-02-21\', \'2\');
INSERT INTO `person` VALUES (\'6\', \'星星\', \'20\', \'女\', \'2000.00\', \'2018-01-30\', \'2\');
INSERT INTO `person` VALUES (\'7\', \'格格\', \'20\', \'女\', \'2000.00\', \'2018-02-27\', \'2\');
INSERT INTO `person` VALUES (\'8\', \'周周\', \'20\', \'女\', \'2000.00\', \'2015-06-21\', \'2\');
-- 市场部
INSERT INTO `person` VALUES (\'9\', \'月月\', \'21\', \'女\', \'4000.00\', \'2014-07-21\', \'3\');
INSERT INTO `person` VALUES (\'10\', \'安琪\', \'22\', \'女\', \'4000.00\', \'2015-07-15\', \'3\');
-- 人事部
INSERT INTO `person` VALUES (\'11\', \'周明月\', \'17\', \'女\', \'5000.00\', \'2014-06-21\', \'4\');
-- 鼓励部
INSERT INTO `person` VALUES (\'12\', \'苍老师\', \'33\', \'女\', \'1000000.00\', \'2018-02-21\', null);
-- 创建表 DROP TABLE IF EXISTS `person`; CREATE TABLE `person` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(50) NOT NULL, `age` tinyint(4) DEFAULT \'0\', `sex` enum(\'男\',\'女\',\'人妖\') NOT NULL DEFAULT \'人妖\', `salary` decimal(10,2) NOT NULL DEFAULT \'250.00\', `hire_date` date NOT NULL, `dept_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=13 DEFAULT CHARSET=utf8; -- 创建数据 -- 教学部 INSERT INTO `person` VALUES (\'1\', \'alex\', \'28\', \'人妖\', \'53000.00\', \'2010-06-21\', \'1\'); INSERT INTO `person` VALUES (\'2\', \'wupeiqi\', \'23\', \'男\', \'8000.00\', \'2011-02-21\', \'1\'); INSERT INTO `person` VALUES (\'3\', \'egon\', \'30\', \'男\', \'6500.00\', \'2015-06-21\', \'1\'); INSERT INTO `person` VALUES (\'4\', \'jingnvshen\', \'18\', \'女\', \'6680.00\', \'2014-06-21\', \'1\'); -- 销售部 INSERT INTO `person` VALUES (\'5\', \'歪歪\', \'20\', \'女\', \'3000.00\', \'2015-02-21\', \'2\'); INSERT INTO `person` VALUES (\'6\', \'星星\', \'20\', \'女\', \'2000.00\', \'2018-01-30\', \'2\'); INSERT INTO `person` VALUES (\'7\', \'格格\', \'20\', \'女\', \'2000.00\', \'2018-02-27\', \'2\'); INSERT INTO `person` VALUES (\'8\', \'周周\', \'20\', \'女\', \'2000.00\', \'2015-06-21\', \'2\'); -- 市场部 INSERT INTO `person` VALUES (\'9\', \'月月\', \'21\', \'女\', \'4000.00\', \'2014-07-21\', \'3\'); INSERT INTO `person` VALUES (\'10\', \'安琪\', \'22\', \'女\', \'4000.00\', \'2015-07-15\', \'3\'); -- 人事部 INSERT INTO `person` VALUES (\'11\', \'周明月\', \'17\', \'女\', \'5000.00\', \'2014-06-21\', \'4\'); -- 鼓励部 INSERT INTO `person` VALUES (\'12\', \'苍老师\', \'33\', \'女\', \'1000000.00\', \'2018-02-21\', null);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#查询语法: select [distinct]*(所有)|字段名,...字段名 from 表名; #查询所有字段信息 select * from person; #查询指定字段信息 select id,name,age,sex,salary from person; #别名查询,使用的as关键字,as可以省略的 select name,age as \'年龄\' ,salary \'工资\' from person; #直接对列进行运算,查询出所有人工资,并每人增加100块. select (5/2); select name, salary+100 from person; #剔除重复查询 select distinct age from person; |
二 条件查询
条件查询:使用 WHERE 关键字 对简单查询的结果集 进行过滤
1. 比较运算符: > < >= <= = <>(!=)
2. null 关键字: is null , not null
3.逻辑运算符: 与 and 或 or (多个条件时,需要使用逻辑运算符进行连接)
1
2
3
4
5
6
7
8
9
10
11
12
|
#查询格式: select [distinct]*(所有)|字段名,...字段名 from 表名 [ where 条件过滤] #比较运算符: > < >= <= = <>(!=) is null 是否为null select * from person where age = 23; select * from person where age <> 23; select * from person where age is null ; select * from person where age is not null ; #逻辑运算符: 与 and 或 or select * from person where age = 23 and salary =29000; select * from person where age = 23 or salary =29000; |
三 区间查询
关键字 between 10 and 20 :表示 获得10 到 20 区间的内容
1
2
3
4
|
# 使用 between...and 进行区间 查询 select * from person where salary between 4000 and 8000; ps: between...and 前后包含所指定的值 等价于 select * from person where salary >= 4000 and salary <= 8000; |
四 集合查询
关键字: in, not null
1
2
3
4
5
6
|
#使用 in 集合(多个字段)查询 select * from person where age in (23,32,18); 等价于: select * from person where age =23 or age = 32 or age =18; #使用 in 集合 排除指定值查询 select * from person where age not in (23,32,18); |
五 模糊查询
关键字 like , not like
%: 任意多个字符
_ : 只能是单个字符
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
#模糊查询 like %:任意多个字符, _:单个字符 #查询姓名以 "张" 字开头的 select * from person where name like \'张%\' ; #查询姓名以 "张" 字结尾的 select * from person where name like \'%张\' ; #查询姓名中含有 "张" 字的 select * from person where name like \'%张%\' ; #查询 name 名称 是四个字符的人 select * from person where name like \'____\' ; #查询 name 名称 的第二个字符是 \'l\' 的人 select * from person where name like \'_l%\' ; #排除名字带 a的学生 select * from student where name not like \'a%\' |
六 排序查询
关键字: ORDER BY 字段1 DESC, 字段2 ASC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#排序查询格式: select 字段|* from 表名 [ where 条件过滤] [order by 字段[ASC][DESC]] 升序:ASC 默认为升序 降序:DESC PS:排序order by 要写在 select 语句末尾 #按人员工资正序排列,注意:此处可以省略 ASC关键字 select * from person order by salary ASC; select * from person order by salary; #工资大于5000的人,按工资倒序排列 select * from person where salary >5000 order by salary DESC; #按中文排序 select * from person order by name; #强制中文排序 select * from person order by CONVERT(name USING gbk); ps:UTF8 默认校对集是 utf8_general_ci , 它不是按照中文来的。你需要强制让mysql按中文来排序 |
七 聚合函数
聚合: 将分散的聚集到一起.
聚合函数: 对列进行操作,返回的结果是一个单一的值,除了 COUNT 以外,都会忽略空值
COUNT:统计指定列不为NULL的记录行数;
SUM:计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0;
MAX:计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算;
MIN:计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算;
AVG:计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0;
1
2
3
4
5
|
#格式: select 聚合函数(字段) from 表名; #统计人员中最大年龄、最小年龄,平均年龄分别是多少 select max(age),min(age),avg(age) from person; |
八 分组查询
分组的含义: 将一些具有相同特征的数据 进行归类.比如:性别,部门,岗位等等
怎么区分什么时候需要分组呢?
套路: 遇到 "每" 字,一般需要进行分组操作.
例如: 1. 公司每个部门有多少人.
2. 公司中有 多少男员工 和 多少女员工.
#分组查询格式: select 被分组的字段 from 表名 group by 分组字段 [having 条件字段] ps: 分组查询可以与 聚合函数 组合使用. #查询每个部门的平均薪资 select avg(salary),dept from person GROUP BY dept; #查询每个部门的平均薪资 并且看看这个部门的员工都有谁? select avg(salary),dept,GROUP_CONCAT(name) from person GROUP BY dept; #GROUP_CONCAT(expr):按照分组,将expr字符串按逗号分隔,组合起来 #查询平均薪资大于10000的部门, 并且看看这个部门的员工都有谁? select avg(salary),dept,GROUP_CONCAT(name) from person GROUP BY dept; having avg(salary)>10000;
where 与 having区别:
#执行优先级从高到低:where > group by > having
#1. Where 发生在分组group by之前,因而Where中可以有任意字段,但是绝对不能使用聚合函数。
#2. Having发生在分组group by之后,因而Having中可以使用分组的字段,无法直接取到其他字段,可以使用聚合函数
九 分页查询
好处:限制查询数据条数,提高查询效率
1
2
3
4
5
6
7
8
9
10
|
#查询前5条数据 select * from person limit 5; #查询第5条到第10条数据 select * from person limit 5,5; #查询第10条到第15条数据 select * from person limit 10,5; ps: limit (起始条数),(查询多少条数); |
十 正则表达式
MySQL中使用 REGEXP 操作符来进行正则表达式匹配。
模式 | 描述 |
---|---|
^ | 匹配输入字符串的开始位置。 |
$ | 匹配输入字符串的结束位置。 |
. | 匹配任何字符(包括回车和新行) |
[...] | 字符集合。匹配所包含的任意一个字符。例如, \'[abc]\' 可以匹配 "plain" 中的 \'a\'。 |
[^...] | 负值字符集合。匹配未包含的任意字符。例如, \'[^abc]\' 可以匹配 "plain" 中的\'p\'。 |
p1|p2|p3 | 匹配 p1 或 p2 或 p3。例如,\'z|food\' 能匹配 "z" 或 "food"。\'(z|f)ood\' 则匹配 "zood" 或 "food"。 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
# ^ 匹配 name 名称 以 "e" 开头的数据 select * from person where name REGEXP \'^e\' ; # $ 匹配 name 名称 以 "n" 结尾的数据 select * from person where name REGEXP \'n$\' ; # . 匹配 name 名称 第二位后包含"x"的人员 "."表示任意字符 select * from person where name REGEXP \'.x\' ; # [abci] 匹配 name 名称中含有指定集合内容的人员 select * from person where name REGEXP \'[abci]\' ; # [^alex] 匹配 不符合集合中条件的内容 , ^表示取反 select * from person where name REGEXP \'[^alex]\' ; #注意1:^只有在[]内才是取反的意思,在别的地方都是表示开始处匹配 #注意2 : 简单理解 name REGEXP \'[^alex]\' 等价于 name != \'alex\' # \'a|x\' 匹配 条件中的任意值 select * from person where name REGEXP \'a|x\' ; #查询以w开头以i结尾的数据 select * from person where name regexp \'^w.*i$\' ; #注意:^w 表示w开头, .*表示中间可以有任意多个字符, i$表示以 i结尾 |
正则详情参考 :http://www.cnblogs.com/wangfengming/articles/8067037.html
十一 SQL 语句关键字的执行顺序
查询:姓名不同人员的最高工资,并且要求大于5000元,同时按最大工资进行排序并取出前5条.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
select name, max(salary) from person where name is not null group by name having max(salary) > 5000 order by max(salary) limit 0,5 |
在上面的示例中 SQL 语句的执行顺序如下:
(1). 首先执行 FROM 子句, 从 person 表 组装数据源的数据
(2). 执行 WHERE 子句, 筛选 person 表中 name 不为 NULL 的数据
(3). 执行 GROUP BY 子句, 把 person 表按 "name" 列进行分组
(4). 计算 max() 聚集函数, 按 "工资" 求出工资中最大的一些数值
(5). 执行 HAVING 子句, 筛选工资大于 5000的人员.
(7). 执行 ORDER BY 子句, 把最后的结果按 "Max 工资" 进行排序.
(8). 最后执行 LIMIT 子句, . 进行分页查询
执行顺序: FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY ->limit
十二 练习题
练习题一: http://www.cnblogs.com/wangfengming/articles/7944029.html
练习题二: http://www.cnblogs.com/wangfengming/articles/7889786.html
以上是关于MySQL 之 单表查询的主要内容,如果未能解决你的问题,请参考以下文章