一, 关键字的执行优先级
1,from: 找到表
2,where: 拿着 where 指定的约束条件, 去文件 / 表中取出一条条数据
3,group by: 将取出的一条条数据进行分组, 如果没有 group by, 则整体作为一组
4,having: 将分组的结果进行 having 过滤
5,select: 执行 select
6,distinct: 去重
7,order by: 将结果按条件排序
8,limit: 限制结果的显示条数
二, 去重, 四则运算, 自定义显示
- # 避免重复 DISTINCT
- SELECT post FROM employee;# 直接这样查询我们会看到很多重复的内容, 我只想看一下有哪些职位, 那么多重复的内容是没用的, 所以我们加一个去重的功能, 叫做 distinct
- SELECT DISTINCT post FROM employee; #对查询出来的记录进行去重, 如果 post 职位有重复的, 就会被剔除, 剩下不重复的内容, 注意, 因为我们查询出来的记录里面只有一个字段 post, 才会根据 post 来进行去重
- SELECT DISTINCT post,salary FROM employee;# 但是如果这样写, 你会发现, 貌似没有起到根据 post 来去重的效果, 因为你的去重条件变成了 post 和 salary 两个字段的数据, 只有他俩合起来是一个重复记录的时候才会去重 #通过四则运算查询
- SELECT name, salary*12 FROM employee; #查询每个人的年薪, 月薪我们有记录, 查年薪呢? 简单的乘以 12 就可以了, from 库. 表的时候, 我们已经通过 use 库名; 来指定了库了, 所以 from 的时候直接写 from 表, 就行了
- #你会发现, 结果是出来了, 但是我们的那个薪资的字段名变成了 salary*12, 是因为我们通过查询语句查询出来的也是一张表, 但是这个表是不是内存当中的一个虚拟表, 并不是我们硬盘中存的那个完整的表, 对吧, 虚拟表是不是也有标题和记录啊,
既然是一个表, 我们是可以指定这个虚拟表的标题的, 通过 as + 新字段名来指定
- SELECT name, salary*12 AS Annual_salary FROM employee; #as + 新字段名, 就是起一个别名的意思, 上面的那个 salary*12 的字段名也是一个别名, 只不过不直观, 是 MySQL 自动给你写上的
- #除了乘法以外, 加减乘除都是可以的
- # 自定义显示格式, 自己规定查询结果的显示格式
CONCAT() 函数用于连接字符串
- SELECT CONCAT('姓名:',name,'年薪:', salary*12) AS Annual_salary #我想让 name 这个字段显示的字段名称是中文的姓名, 让 salary*12 显示的是中文的年薪,
- FROM employee;# 看结果: 通过结果你可以看出, 这个 concat 就是帮我们做字符串拼接的, 并且拼接之后的结果, 都在一个叫做 Annual_salary 的字段中了
- +---------------------------------------+
- | Annual_salary |
- +---------------------------------------+
| 姓名: egon 年薪: 87603.96 |
| 姓名: alex 年薪: 12000003.72 |
| 姓名: wupeiqi 年薪: 99600.00 |
| 姓名: yuanhao 年薪: 42000.00 |
- .....
- +---------------------------------------+
- SELECT CONCAT('姓名:',name,'年薪:', salary*12) AS Annual_salary,CONCAT('性别:',sex) from employee;# 还可以这样分成两列
CONCAT_WS() 第一个参数为分隔符来进行字符串拼接
SELECT CONCAT_WS(':',name,salary*12) AS Annual_salary from employee; #通过冒号来将 name 和 salary 连接起来 #上面这个效果我们也可以通过 concat 来实现: SELECT CONCAT(name,':',salary*12) AS Annual_salary from employee;
三, where 约束
1, 比较运算符:> <>= <= <> !=
- ,between 80 and 100
- ,in(80,90,100)
4,like 'ee%' 模糊匹配,% 表示任意多字符,_表示一个字符
5, 逻辑运算符: 在多个条件直接可以用逻辑运算符 and or not
- #1: 单条件查询
- SELECT name FROM employee WHERE post='sale'; #注意优先级, 我们说 where 的优先级是不是比 select 要高啊, 所以我们的顺序是先找到这个 employee 表, 然后按照 post='sale'的条件, 然后去表里面 select 数据
- #2: 多条件查询
- SELECT name,salary FROM employee WHERE post='teacher' AND salary>10000;
- #3: 关键字 BETWEEN AND 写的是一个区间
- SELECT name,salary FROM employee WHERE salary BETWEEN 10000 AND 20000; #就是 salary>=10000 and salary<=20000 的数据
- SELECT name,salary FROM employee WHERE salary NOT BETWEEN 10000 AND 20000; #加个 not, 就是不在这个区间内, 薪资小于 10000 的或者薪资大于 20000 的, 注意没有等于,
- #4: 关键字 IS NULL(判断某个字段是否为 NULL 不能用等号, 需要用 IS) 判断 null 只能用 is
- SELECT name,post_comment FROM employee WHERE post_comment IS NULL;
- SELECT name,post_comment FROM employee WHERE post_comment IS NOT NULL#5: 关键字 IN 集合查询
- SELECT name,salary FROM employee WHERE salary=3000 OR salary=3500 OR salary=4000 OR salary=9000 ; #这样写是不是太麻烦了, 写一大堆的 or, 下面我们用 in 这个简单的写法来搞
- SELECT name,salary FROM employee WHERE salary IN (3000,3500,4000,9000) ;
- SELECT name,salary FROM employee WHERE salary NOT IN (3000,3500,4000,9000) ;
- #6: 关键字 LIKE 模糊查询, 模糊匹配, 可以结合通配符来使用
通配符'%' #匹配任意所有字符
SELECT * FROM employee WHERE name LIKE 'eg%';
通配符'_' #匹配任意一个字符
SELECT * FROM employee WHERE name LIKE 'al__'; #注意我这里写的两个_, 用 1 个的话, 匹配不到 alex, 因为 al 后面还有两个字符 ex.
四, 分组查询 group by
select * from 表名 group by 字段
对 sql_mode 进行设置为 ONLY_FULL_GROUP_BY, 此时就会报错, 只能查看该字段的内容, 但如果没有设定, 也只会显示每组的第一组数据
单独使用 GROUP BY 关键字分组
SELECT post FROM employee GROUP BY post;
注意: 我们按照 post 字段分组, 那么 select 查询的字段只能是 post, 想要获取组内的其他相关信息, 需要借助函数
GROUP BY 关键字和 GROUP_CONCAT() 函数一起使用, 比如说我想按部门分组, 每个组有哪些员工, 都显示出来, 怎么搞
- SELECT post,GROUP_CONCAT(name) FROM employee GROUP BY post;# 按照岗位分组, 并查看组内所有成员名, 通过逗号拼接在一起
- SELECT post,GROUP_CONCAT(name,':',salary) as emp_members FROM employee GROUP BY post;
GROUP BY 一般都会与聚合函数一起使用, 聚合是什么意思: 聚合就是将分组的数据聚集到一起, 合并起来搞事情, 拿到一个最后的结果
select post,count(id) as count from employee group by post;# 按照岗位分组, 并查看每个组有多少人, 每个人都有唯一的 id 号, 我 count 是计算一下分组之后每组有多少的 id 记录, 通过这个 id 记录我就知道每个组有多少人了
关于集合函数, MySQL 提供了以下几种聚合函数: count,max,min,avg,sum 等, 上面的 group_concat 也算是一个聚合函数了, 做字符串拼接的操作
五, 过滤 having
执行优先级: where,group by,having
where 发生在 group 之前, 因而 where 可以用任意字段, 但绝不能用聚合函数
having 发生在 group by 之后, 因而可以用分组的字段, 无法直接用到其他字段, having 是可以用聚合函数的
select post,avg(salary) from t1 where age> 30 group by post having avg(salary)>10000;
这是得到各部门年龄大于 30 的员工的平均工资, 最后保留平均工资大于 10000 的部门
六, 查询排序 order by
- select * from t1 order by salary #默认升序排列
- select * from t1 order by salary asc; #升序排列
- select * from t1 order by salary desc; #降序排列
- select * from t1 order by age asc,salary desc; #先以年龄升序排列, 若年龄相同的就以工资降序排列
七, 限制查询的记录数 limit
- select * from t1 order by salary limit 3; #默认起始位为 0, 即从第一条数据开始, 总共显示 3 条数据
- select * from t1 order by salary desc limit 0,5; #起始位为 0, 即从第一条开始, 总共显示 5 条数据
- select * from t1 order by salary asc limit 2,6; #起始位为 2, 即从第三条开始, 总共显示 6 条数据
八, 使用正则表达式查询
之前用的 like 是模糊匹配, 只有 % 和_, 具有局限性, 查询的时候其实可以用我们之前学正则
- select * from t1 where name regexp '^ale'; #匹配以 ale 开头的
- select * from t1 where name regexp 'ss$'; #匹配以 ss 结尾的
- select * from t1 where name regexp 'm{2}' #匹配含有 2 个 m 的
对字符串匹配的方式:
- where name = 'ee' #查找 name 是'ee'的数据
- where name like 'yu%' #查找以 yu 开头的数据
- where name regexp 'euu$' #查找以 euu 结尾的数据
来源: http://www.linuxidc.com/Linux/2018-12/155762.htm