python-day43--单表查询之关键字执行优先级(重点)

一、关键字的执行优先级(重点)

1.关键字执行优先级

from
where        #约束条件(在数据产生之前执行)
group by     #分组    没有分组则默认一组
按照select后的字段取得一张新的虚拟表,有聚合函数则执行聚合函数
having         #过滤条件 ,having 是根据内存中的虚拟表 过滤的 ;出现having的时候肯定是有group by,不然没意义    
distinct     #去重        #在select 之后执行  忽略先后顺序
order by     #排序          #在select 之后执行  忽略先后顺序
limit        #限制查询的记录数    #在select 之后执行  忽略先后顺序

  1.找到表:from
  2.拿着where指定的约束条件,去文件/表中取出一条条记录
  3.将取出的一条条记录进行分组group by,如果没有group by,则整体作为一组
  4.按照select后的字段得到一张新的虚拟表,如果有聚合函数,则将组内数据进行聚合
  5.将4的结果过滤:having
  6.查出结果:select
  7.去重
  8.将结果按条件排序:order by
  9.限制结果的显示条数

2.having与where不一样的地方在于!!!!!!

#!!!执行优先级从高到低:where > group by > 聚合函数 > having 
#1. Where 是一个约束声明,使用Where约束来自数据库的数据,Where是在结果返回之前起作用的(先找到表,按照where的约束条件,从表(文件)中取出数据),Where中不能使用聚合函数。
#2. Having是一个过滤声明,是在查询返回结果集以后对查询结果进行的过滤操作(先找到表,按照where的约束条件,从表(文件)中取出数据,然后group by分组,如果没有group by则所有记录整体为一组,然后执行聚合函数,然后使用having对聚合的结果进行过滤),在Having中可以使用聚合函数。
#3. having可以放到group by之后,而where只能放到group by之前
#4. 在查询过程中聚合语句(sum,min,max,avg,count)要比having子句优先执行。而where子句在查询过程中执行优先级高于聚合语句。

验证不同之处:

#验证之前再次强调:执行优先级从高到低:where > group by > 聚合函数 > having 
select count(id) from employee where salary > 10000; #正确,分析:where先执行,后执行聚合count(id),然后select出结果
select count(id) from employee having salary > 10000;#错误,分析:先执行聚合count(id),后执行having过滤,无法对id进行salary>10000的过滤

以上两条sql的顺序是:

1:找到表employee--->用where过滤---->没有分组则默认一组执行聚合count(id)--->select执行查看组内id数目
2:找到表employee--->没有分组则默认一组执行聚合count(id)---->having 基于上一步聚合的结果(此时只有count(id)字段了)进行salary>10000的过滤,很明显,根本无法获取到salary字段

其他需要注意的问题:

select post,group_concat(name) from employee group by post having salary > 10000;#错误,分组后无法直接取到salary字段
select post,group_concat(name) from employee group by post having avg(salary) > 10000; 正确

例子:

例子:
select max(salary) from t1 where id > 2 group by depart_id having count(id) > 2;
执行顺序: from t1 ——> where id >2  ——>  group by depart_id ——>  max(salary)和count(id) 然后才执行 having count(id) >2   最后打印

辅助理解:select 333333333 from t1 where id > 2 group by depart_id having 4 > 2;

练习:

#练习
select post,count(id),group_concat(name) from emp group by post having count(id) < 2;      #可以运行
select count(id) from emp having id > 15;            #运行错误

3.命名

命名:
select post,avg(salary) as 平均工资 from emp group by post having avg(salary) > 10000;
select post 岗位名,avg(salary) 平均工资 from emp group by post having avg(salary) > 10000;    #命名时 as 可以省略

4.order by关键字

select * from emp order by salary;    #默认就是升序
select * from emp order by salary asc; #升序
select * from emp order by salary desc; #降序
select * from emp order by age asc,salary desc; #先按照年龄从小到大排,如果年龄分不出胜负(即值相同)再按照salary从大到小排。

练习:

select * from emp order by age asc,hire_date desc;
select post 岗位名,avg(salary) 平均工资 from emp group by post having avg(salary) > 10000 order by avg(salary) asc;

5.通过四则运算查询:

select name, salary*12 AS Annual_salary FROM employee;
select name, salary*12 Annual_salary FROM employee;
select * from employee where id%2=1;  

6.定义显示格式:

1.CONCAT() 函数用于连接字符串
   SELECT CONCAT('姓名: ',name,'  年薪: ', salary*12)  AS Annual_salary FROM employee;
   
mysql> SELECT CONCAT('姓名: ',name,'  年薪: ', salary*12)  AS Annual_salary
    ->    FROM emp;
+---------------------------------------+
| Annual_salary                         |
+---------------------------------------+
| 姓名: egon  年薪: 87603.96            |
| 姓名: alex  年薪: 12000003.72         |
| 姓名: wupeiqi  年薪: 99600.00         |
| 姓名: yuanhao  年薪: 42000.00         |
| 姓名: liwenzhou  年薪: 25200.00       |
| 姓名: jingliyang  年薪: 108000.00     |
| 姓名: jinxin  年薪: 360000.00         |
| 姓名: 成龙  年薪: 120000.00           |
| 姓名: 歪歪  年薪: 36001.56            |
| 姓名: 丫丫  年薪: 24004.20            |
| 姓名: 丁丁  年薪: 12004.44            |
| 姓名: 星星  年薪: 36003.48            |
| 姓名: 格格  年薪: 48003.96            |
| 姓名: 张野  年薪: 120001.56           |
| 姓名: 程咬金  年薪: 240000.00         |
| 姓名: 程咬银  年薪: 228000.00         |
| 姓名: 程咬铜  年薪: 216000.00         |
| 姓名: 程咬铁  年薪: 204000.00         |
+---------------------------------------+
18 rows in set (0.00 sec)

2.CONCAT_WS() 第一个参数为分隔符
   SELECT CONCAT_WS(':',name,salary*12)  AS Annual_salary FROM employee;


mysql> SELECT CONCAT_WS(':',name,salary*12)  AS Annual_salary
    ->    FROM emp;
+----------------------+
| Annual_salary        |
+----------------------+
| egon:87603.96        |
| alex:12000003.72     |
| wupeiqi:99600.00     |
| yuanhao:42000.00     |
| liwenzhou:25200.00   |
| jingliyang:108000.00 |
| jinxin:360000.00     |
| 成龙:120000.00       |
| 歪歪:36001.56        |
| 丫丫:24004.20        |
| 丁丁:12004.44        |
| 星星:36003.48        |
| 格格:48003.96        |
| 张野:120001.56       |
| 程咬金:240000.00     |
| 程咬银:228000.00     |
| 程咬铜:216000.00     |
| 程咬铁:204000.00     |
+----------------------+
18 rows in set (0.00 sec)

7. limit   限制查询的记录数

  1. select * from emp limit 10;     #第一条到第十条记录

mysql> select * from emp limit 10;
+----+------------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
| id | name       | sex    | age | hire_date  | post                                    | post_comment | salary     | office | depart_id |
+----+------------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
|  1 | egon       | male   |  18 | 2017-03-01 | 老男孩驻沙河办事处外交大使              | NULL         |    7300.33 |    401 |         1 |
|  2 | alex       | male   |  78 | 2015-03-02 | teacher                                 | NULL         | 1000000.31 |    401 |         1 |
|  3 | wupeiqi    | male   |  81 | 2013-03-05 | teacher                                 | NULL         |    8300.00 |    401 |         1 |
|  4 | yuanhao    | male   |  73 | 2014-07-01 | teacher                                 | NULL         |    3500.00 |    401 |         1 |
|  5 | liwenzhou  | male   |  28 | 2012-11-01 | teacher                                 | NULL         |    2100.00 |    401 |         1 |
|  6 | jingliyang | female |  18 | 2011-02-11 | teacher                                 | NULL         |    9000.00 |    401 |         1 |
|  7 | jinxin     | male   |  18 | 1900-03-01 | teacher                                 | NULL         |   30000.00 |    401 |         1 |
|  8 | 成龙       | male   |  48 | 2010-11-11 | teacher                                 | NULL         |   10000.00 |    401 |         1 |
|  9 | 歪歪       | female |  48 | 2015-03-11 | sale                                    | NULL         |    3000.13 |    402 |         2 |
| 10 | 丫丫       | female |  38 | 2010-11-01 | sale                                    | NULL         |    2000.35 |    402 |         2 |
+----+------------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
10 rows in set (0.00 sec)
View Code

  2.从哪开始,往后取几条    第一个数字表示的是索引,第二个代表步距
  select * from emp limit 0,3;    #第一条开始往后三条

select * from emp limit 0,3;    #第一条开始往后三条

+----+---------+------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
| id | name    | sex  | age | hire_date  | post                                    | post_comment | salary     | office | depart_id |
+----+---------+------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
|  1 | egon    | male |  18 | 2017-03-01 | 老男孩驻沙河办事处外交大使              | NULL         |    7300.33 |    401 |         1 |
|  2 | alex    | male |  78 | 2015-03-02 | teacher                                 | NULL         | 1000000.31 |    401 |         1 |
|  3 | wupeiqi | male |  81 | 2013-03-05 | teacher                                 | NULL         |    8300.00 |    401 |         1 |
+----+---------+------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
3 rows in set (0.00 sec)

select * from emp limit 3,3;

+----+------------+--------+-----+------------+---------+--------------+---------+--------+-----------+
| id | name       | sex    | age | hire_date  | post    | post_comment | salary  | office | depart_id |
+----+------------+--------+-----+------------+---------+--------------+---------+--------+-----------+
|  4 | yuanhao    | male   |  73 | 2014-07-01 | teacher | NULL         | 3500.00 |    401 |         1 |
|  5 | liwenzhou  | male   |  28 | 2012-11-01 | teacher | NULL         | 2100.00 |    401 |         1 |
|  6 | jingliyang | female |  18 | 2011-02-11 | teacher | NULL         | 9000.00 |    401 |         1 |
+----+------------+--------+-----+------------+---------+--------------+---------+--------+-----------+
3 rows in set (0.00 sec)


select * from emp limit 6,3;

 +----+--------+--------+-----+------------+---------+--------------+----------+--------+-----------+
| id | name   | sex    | age | hire_date  | post    | post_comment | salary   | office | depart_id |
+----+--------+--------+-----+------------+---------+--------------+----------+--------+-----------+
|  7 | jinxin | male   |  18 | 1900-03-01 | teacher | NULL         | 30000.00 |    401 |         1 |
|  8 | 成龙   | male   |  48 | 2010-11-11 | teacher | NULL         | 10000.00 |    401 |         1 |
|  9 | 歪歪   | female |  48 | 2015-03-11 | sale    | NULL         |  3000.13 |    402 |         2 |
+----+--------+--------+-----+------------+---------+--------------+----------+--------+-----------+
3 rows in set (0.00 sec)   
View Code

8.distinct  去重

select distinct sex from emp;

+--------+
| sex    |
+--------+
| male   |
| female |
+--------+
2 rows in set (0.00 sec)

9.where name 正则

SELECT * FROM employee WHERE name REGEXP '^ale';

SELECT * FROM employee WHERE name REGEXP 'on$';

SELECT * FROM employee WHERE name REGEXP 'm{2}';


小结:对字符串匹配的方式
WHERE name = 'egon';
WHERE name LIKE 'yua%';
WHERE name REGEXP 'on$';

  小练习:查看所有员工中名字是jin开头,n或者g结果的员工信息

select * from employee where name regexp '^jin.*[gn]$';
View Code
原文地址:https://www.cnblogs.com/liuwei0824/p/7497969.html