數據庫的完整查詢語法
在平常的工作中經常需要與數據庫打交道 , 雖然大多時間都是簡單的查詢抑或使用框架封裝好的ORM的查詢方法 , 但是還是要對數據庫的完整查詢語法做一個加深理解
數據庫完整查詢語法框架
select [distinct] 字段1 [as 別名], ..., 字段n [as 別名] from [庫名.]表名 [ where 約束條件 group by 分組依據 having 過濾條件 order by 排序的字段 limit 限制顯示的條數 ]; 注: 1.查表中所有字段用*表示(select * from ...) 2.條件的書寫規則嚴格按照語法順序書寫,可以缺省,但不可以錯序 3.約束條件的流程:from -> where -> group by -> having -> distinct -> order by -> limit 4.字段可以起別名 5.字段可以直接做運算 select age + 1 'new_age' from emp; 6.分組后的條件均可以使用聚合函數 ''' ''' 3. 偽代碼解析流程 def from(): return "查詢的文件" def where(file): return "條件篩選后的結果" def group_by(res): return "分組后的結果" def having(res): return "再次過濾后的結果" def distinct(res): return "去重后的結果" def order_by(res): return "排序后的結果" def limit(res): return "限制條數后的結果" def select(from=from, where=null, ..., limit=null): file = from() res = where(file) if where else file res = group_by(res) if group_by else res ... res = limit(res) if limit else res return res select(where=where, group_by=group_by)
-
基礎語法
- select field_name from Table_name >>> 表中單個字段查詢
- select * from Table_name >>> 表中所有字段查詢
-
where 條件
- 條件可以是各種運算及正則匹配
1. 比較運算符 ``` = < > <= >= != ``` ``` select * from emp where area!="上海"; ``` 2. 區間運算符 between 10 and 20 # 表示10-20 之間 in (10,20,30) # 表示10,20或者30 ``` select * from emp where id between 3 and 5; # [3, 5], 閉合區間,包含3和5 ``` 3. 邏輯運算符 and or not ``` select * from emp where area='山東' and port='濟南'; mysql> select * from emp where area='山東' and port='濟南'; +----+-------+--------+------+--------+--------+--------+-----------+ | id | name | gender | age | salary | area | port | dep | +----+-------+--------+------+--------+--------+--------+-----------+ | 2 | owen | 男 | 38 | 9.4 | 山東 | 濟南 | 技術部 | | 10 | kevin | 男 | 36 | 5.8 | 山東 | 濟南 | 人資部 | +----+-------+--------+------+--------+--------+--------+-----------+ 2 rows in set (0.00 sec) ``` 4. 相似運算符(like) 下划線或者%可以進行模糊匹配 ``` select * from emp where name like '__en%'; # 匹配出Owen mysql> select * from emp where name like '__en%'; +----+------+--------+------+--------+--------+--------+-----------+ | id | name | gender | age | salary | area | port | dep | +----+------+--------+------+--------+--------+--------+-----------+ | 7 | owen | 男 | 28 | 8.8 | 安徽 | 宣城 | 技術部 | +----+------+--------+------+--------+--------+--------+-----------+ 1 row in set (0.00 sec) ``` 5. 正則匹配(regexp) - 由於like完成模糊匹配的范圍有限 , 可以模糊個數 , 但不能模糊類型 - ------正則可以完成類型和個數的模糊匹配(只支持部分語法) ```python select * from emp where name regexp '.*[0-9]+.*'; # 匹配出名字中帶數字的記錄 mysql> select * from emp where name regexp '.*[0-9]+.*'; +----+------+--------+------+--------+--------+--------+-----------+ | id | name | gender | age | salary | area | port | dep | +----+------+--------+------+--------+--------+--------+-----------+ | 13 | san1 | 男 | 30 | 6 | 上海 | 浦東 | 咨詢部 | | 14 | san2 | 男 | 30 | 6 | 上海 | 浦西 | 研發部 | +----+------+--------+------+--------+--------+--------+-----------+ 2 rows in set (0.00 sec) ```
-
group by 分組依據
- 以記錄的字段共性對記錄進行分組
- 分組后字段可進行聚合函數處理
___聚合函數___ max():最大值 min():最小值 avg():平均值 sum():和 count():記數 group_concat():組內字段拼接,用來查看組內其他字段
___example___
# eg1
# 每個部門的平均薪資
select dep, avg(salary) '平均薪資' from emp group by dep;
mysql> select dep, avg(salary) '平均薪資' from emp group by dep;
+-----------+-------------------+
| dep | 平均薪資 |
+-----------+-------------------+
| 咨詢部 | 6.250000059604645 |
| 人資部 | 5.400000027247837 |
| 技術部 | 5.850000023841858 |
+-----------+-------------------+
3 rows in set (0.00 sec)
# eg:2
# 每個部門都有哪些人
select dep, group_concat(name) 'name' from emp group by dep;
mysql> select dep,group_concat(name) 'name' from emp group by dep;
+-----------+---------------------------------------+
| dep | name |
+-----------+---------------------------------------+
| 咨詢部 | san1,san,ying,zero |
| 技術部 | san2,kevin,owen,jiboy,tank,jerry,engo |
| 人資部 | monkey,yangsir |
+-----------+---------------------------------------+
3 rows in set (0.04 sec)
# eg3
# 各性別中附屬於教學部的最高薪資
select max(salary) '最高薪資', gender from emp where dep='教學部' group by gender;
-
having 篩選
- 對where和group by處理的結果進一步篩選 , 得到我們想要的數據
1.各部門的平均薪資 select dep, avg(salary) '平均薪資' from emp group by dep; 2.平均薪資大於6w的部門(部門與部門的平均薪資) 解決: 以dep進行分組, 以avg(salary)作為判斷條件(篩選) select dep, avg(salary) '平均薪資' from emp group by dep having avg(salary) > 6; # 總結: having通過聚合函數結果完成篩選 select max(salary) from emp having max(salary) > 9.4; # 雖然沒有明確書寫group by, 但在having中使用了聚合函數,所以該查詢就將整個表當做一個默認大表來考慮,所以查詢的字段只能為聚合函數的結果
-
order by 排序
- 對篩選結果進行升序或者降序排列(默認是升序)
- 升序: asc ; 降序: desc
# eg:order by age desc => 按照年齡降序 select * from emp order by age desc; # 需求: # 將部門按照部門平均工資降序方式排序 select dep, avg(salary) from emp group by dep order by avg(salary) desc;
-
limit 限制
- 顯示最終數據結果的行數 , 只能與數字配合使用
# limit 1:只能顯示一行數據 # limit 6,5:從第6+1行開始顯示5條數據(索引從0開始) select * from emp limit 1; select * from emp limit 6,5; # 需求: # 獲得薪資最高的人的一條信息 select * from emp order by salary desc limit 1;
總結下來 , 對舊的知識又有了新的認識.....想起這並不是最完整的查詢語法 , 更加完整的查詢語法應該還要算上子查詢與父查詢, 時間太晚,未完待續......