數據庫(七):單表查詢


進擊のpython

*****

數據庫——單表查詢


數據庫在使用的時候,更多的是查看數據,而學會了外鍵之后,查詢就已經不僅僅是針對單個表的操作了

同時,對於單表的查詢要求也是越來越高,而基於此,原先的簡單查詢就有點心有余而力不足了

所以說,接下來就是進階的查詢!首先要確定一點的就是,查詢是針對記錄的,這點要明確哦


單表查詢

既然是進階,就一定有不一樣的花板子~完整的單表查詢指令如下:

select distinct字段名1,字段名2 from 庫.表 

where 條件

group by 分組

having 過濾

order by 排序

limit 限制

;

簡單查詢

distinct:去重

mysql> select post from employee;
+-----------------------------------------+
| post                                    |
+-----------------------------------------+
| 駐沙河辦事處外交大使                       |
| teacher                                 |
| teacher                                 |
| teacher                                 |
| teacher                                 |
| teacher                                 |
| teacher                                 |
| teacher                                 |
| sale                                    |
| sale                                    |
| sale                                    |
| sale                                    |
| sale                                    |
| operation                               |
| operation                               |
| operation                               |
| operation                               |
| operation                               |
+-----------------------------------------+
18 rows in set (0.00 sec)

mysql> select distinct post from employee;
+-----------------------------------------+
| post                                    |
+-----------------------------------------+
| 駐沙河辦事處外交大使                      |
| teacher                                 |
| sale                                    |
| operation                               |
+-----------------------------------------+
4 rows in set (0.32 sec)

同時查詢的時候是支持四則運算的:

mysql> select name,salary*12 from employee;
+------------+-------------+
| name       | salary*12   |
+------------+-------------+
| 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)

mysql> select name,salary*12 as annual_salary from employee;
+------------+---------------+
| name       | 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.37 sec)

看到為什么寫兩個了吧,看到區別了吧~

還有就是字符串拼接,怎么拼接呢?

select concat('name:',name) from employee;

mysql> select concat('name:',name) from employee;
+------------------------+
| concat('name:',name)  |
+------------------------+
| name:egon             |
| name:alex             |
| name:wupeiqi          |
| name:yuanhao          |
| name:liwenzhou        |
| name:jingliyang       |
| name:jinxin           |
| name:成龍             |
| name:歪歪             |
| name:丫丫             |
| name:丁丁             |
| name:星星             |
| name:格格             |
| name:張野             |
| name:程咬金           |
| name:程咬銀           |
| name:程咬銅           |
| name:程咬鐵           |
+------------------------+
18 rows in set (0.00 sec)


where約束

where字句中可以使用:

  1. 比較運算符:> < >= <= <> !=
  2. between 80 and 100 值在80到100之間
  3. in(80,90,100) 值是10或20或30
  4. like 'ponny%'
    pattern可以是%或_,
    %表示任意多字符
    _表示一個字符
  5. 邏輯運算符:在多個條件直接可以使用邏輯運算符 and or not

這個一部分講的在前面都有涉及,所以,就不舉例了,你自己嘗試使用

group by

這是分組,分組就是把有相同或相似特征的放在一起

比如說把男的都放在一起,把女的都放在一起

而且group by 只能夠查詢該分組的組名,查不到別的東西

mysql> select * from employee group by post;
+----+--------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
| id | name   | sex    | age | hire_date  | post                                    | post_comment | salary     | office | depart_id |
+----+--------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
| 14 | 張野   | male   |  28 | 2016-03-11 | operation                               | NULL         |   10000.13 |    403 |         3 |
|  9 | 歪歪   | female |  48 | 2015-03-11 | sale                                    | NULL         |    3000.13 |    402 |         2 |
|  2 | alex   | male   |  78 | 2015-03-02 | teacher                                 | NULL         | 1000000.31 |    401 |         1 |
|  1 | egon   | male   |  18 | 2017-03-01 | 駐沙河辦事處外交大使              | NULL         |    7300.33 |    401 |         1 |
+----+--------+--------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
4 rows in set (0.41 sec)

你這不騙我嗎?哪只有分組數據啊,這么多數據呢!

但是你會發現打印出來的都是每組的第一條數據,這是沒有意義的

別慌,其實這是mysql的設定,我們需要把模式改成嚴格模式才可以

set global sql_mode='ONLY_FULL_GROUP_BY';

怎么設置完還這樣呢?還記得設置自增時候的步長和起始偏移量的時候嗎?我們需要關掉重開一下!

mysql> select * from employee group by post;
ERROR 1055 (42000): 't.employee.id' isn't in GROUP BY

但是其實也沒有用,因為分組的目的不是想看看同類的,而是想對這些人做一個數據處理

比如像想統計人數啊之類的~~那就用到了聚合函數了!

那題道具和函數,就得好好說或聚合函數,聚合函數一共有這些:

max min avg sum count

比如說我們統計一下每個職位的人數~

select count(id) from employee group by post

mysql> select post,count(name) from employee group by post;
+-----------------------------------------+-------------+
| post                                    | count(name) |
+-----------------------------------------+-------------+
| operation                               |           5 |
| sale                                    |           5 |
| teacher                                 |           7 |
| 駐沙河辦事處外交大使                	  |           1 |
+-----------------------------------------+-------------+

4 rows in set (0.00 sec)

要是想打印人數大於五的部門信息那我應該是這么寫:

select concat('職位:',post,'	人數:',count(name),
'	姓名:',group_concat(name)) as info,
count(name)>5 from employee group by post;

尤其是看到group_concat(name)的用法!!!

你可能執行的結果是這個:

+--------------------------------------------------------------------------------------------+--------+
| info                                                                                       | 數量   |
+--------------------------------------------------------------------------------------------+--------+
| 職位:operation人數:5姓名:程咬鐵,程咬銅,程咬銀,程咬金,張野                               |      0 |
| 職位:sale人數:5姓名:格格,星星,丁丁,丫丫,歪歪                                            |      0 |
| 職位:teacher人數:7姓名:成龍,jinxin,jingliyang,liwenzhou,yuanhao,wupeiqi,alex            |      1 |
| 職位:駐沙河辦事處外交大使人數:1姓名:egon                                          |      0 |
+--------------------------------------------------------------------------------------------+--------+

這跟本來想的不一樣啊!別急~~~你還差一個知識點!先放在這

那我們可以逆向思維,如果不分組,是不是,就所有數據都是一組了!

那是不是也可以用聚合函數!

那我比如說想查找最高工資,是不是就會了!

having

這就是差的知識點!having 過濾

誒???我好像記得之前也有個過濾,好像是where,那他們有什么區別嗎?

#!!!執行優先級從高到低:where > group by > having 
#1. Where 發生在分組group by之前,因而Where中可以有任意字段,但是絕對不能使用聚合函數。

#2. Having發生在分組group by之后,因而Having中可以使用分組的字段,無法直接取到其他字段,可以使用聚合函數

(驗證自己驗證ok?)

那餓哦們就可以接着把上面的代碼優化為:

select concat('職位:',post,'人數:',count(name),'姓名:',group_concat(name)) info from employee group by post having count(id)>5;

這回再打印,是不是就是預料之中的結果了!

order by

排序

表格默認的是id排序,那我想根據年齡排序,怎么辦呢?

select * from employee order by age;

可以看到是默認升序,那要是想要倒序呢?

select * from employee order by age desc

那你可能發現age有相等的時候,那我要是想相等的時候按照id排序怎么做呢?

select * from employee order by age,id

limit 限制

這個就是限制顯示條數,限制顯示前三條:

mysql> select * from employee limit 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.09 sec)

當然它其實還有分頁的功能:

select * from employee limit 0,5;代表着從0開始往后取5個

(表結構看不清就看id)

 select * from employee limit 0,5;
+----+-----------+------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
| 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 |
+----+-----------+------+-----+------------+-----------------------------------------+--------------+------------+--------+-----------+
5 rows in set (0.00 sec)

從5開始往后取五個:

mysql> select * from employee limit 5,5;
+----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+
| id | name       | sex    | age | hire_date  | post    | post_comment | salary   | office | depart_id |
+----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+
|  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 |
+----+------------+--------+-----+------------+---------+--------------+----------+--------+-----------+
5 rows in set (0.00 sec)

接下來的分頁就不演示了~

那在這我就要提一下書寫順序和執行順序了,畢竟約束條件這么多,總要有個優先級嘛:

正則表達式

where 后面雖然不能使用聚合函數,但是是可以使用正則匹配的

selece * from employee where name regexp '^ale'; 以ale開頭的

其實他跟select * from employee where name like 'ale%';是一樣的

select * from employee where name regexp 'on$'; 以on結尾的

select * from employee where name regexp 'm{2}'; 里面有mm的

以上的方法都自己去試一下

那我要是想以什么開頭,以什么結尾呢?

select * from employee where name regexp '^jin.*(g|n)$';

這就是以 jin 開頭,以g或者n結尾的name字段的數據

那至此,所有的約束就全結束了!

接下來就是多表查詢了~


*****
*****


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM