1. 程式人生 > >python-day43--單表查詢之關鍵字執行優先級(重點)

python-day43--單表查詢之關鍵字執行優先級(重點)

exp 連接字符串 四則運算 img isp 數字 group 強調 alex

一、關鍵字的執行優先級(重點)

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

python-day43--單表查詢之關鍵字執行優先級(重點)