文章目錄
- day01課堂筆記
- 1、數據庫概述及數據準備
- 1.1、什么是數據庫
- 1.2、什么是數據庫管理系統
- 1.3、SQL概述
- 1.4、安裝MySQL數據庫管理系統。
- 1.4、MySQL數據庫的完美卸載!
- 1.5、MySQL的服務
- 1.6、用命令來啟動和關閉mysql服務
- 1.7、登錄mysql數據庫
- 2、MySQL常用命令:
- 2.1、數據庫當中最基本的單元是:表
- 2.2、關于SQL語句的分類?
- 2.3、導入一下提前準備好的數據:
- 3、查看表結構
- 4、簡單查詢
- 4.1、查詢一個字段?
- 4.2、查詢多個字段
- 4.3、查詢全部字段
- 4.4、給查詢的列起別名
- 4.5、計算員工年薪?
- 5、條件查詢
- 5.1、什么是條件查詢?
- 5.2、都有哪些條件?
- 6、排序數據
- 6.1、單一字段排序
- 6.2、手動指定排序順序
- 6.3、多個字段排序
- 6.4、根據字段的位置排序
- 6.5、綜合一點的案例:
- 7、數據處理函數
- 單行處理函數常見的有哪些?
- 8、分組函數(多行處理函數)
- 9、分組查詢(非常重要:五顆星)
- 9.1、什么是分組查詢?
- 9.2、將之前的關鍵字全部組合在一起,來看一下他們的執行順序?
- 9.3、找出每個工作崗位的工資和?
- 9.4、找出每個部門的最高薪資
- 9.5、找出“每個部門,不同工作崗位”的最高薪資?
- 9.6、having
- 9.7、where沒辦法的
- 9.8、大總結(單表的查詢)
day01課堂筆記
每天晚上敲兩邊
逗號使用:函數當中的值,字段與字段之間
本文章為學習動力節點的杜老師,視頻鏈接如下
https://www.bilibili.com/video/BV1Vy4y1z7EX
源碼+文檔+學習資料+安裝工具[點贊]都已經為大家準備好!!!!鏈接:https://pan.baidu.com/s/1PTbdG-olm8mpEzz-zXe6bw
提取碼:m0bc
1、數據庫概述及數據準備
1.1、什么是數據庫
數據庫:英文單詞DataBase,簡稱DB。
? 按照一定格式存儲數據的一些文件的組合。
? 顧名思義:存儲數據的倉庫,實際上就是一堆文件。這些文件中存儲了具有特定格式的數據。
1.2、什么是數據庫管理系統
數據庫管理系統:DataBaseManagement,簡稱DBMS。
? 數據庫管理系統是專門用來管理數據庫中數據的,數據庫管理系統可以對數據庫當中的數據進行增刪改查。
? 常見的數據庫管理系統:
? MySQL、Oracle、MS SqlServer、DB2、sybase等…
1.3、SQL概述
SQL:結構化查詢語言
程序員需要學習SQL語句,程序員通過編寫SQL語句,然后DBMS負責執行SQL語句,最終來完成數據庫中數據的增刪改查操作。
? SQL是一套標準,程序員主要學習的就是SQL語句,這個SQL在mysql中可以使用,同時在Oracle中也可以使用,在DB2中也可以使用。
三者之間的關系?
? DBMS–執行–> SQL --操作–> DB
先安裝數據庫管理系統MySQL,然后學習SQL語句怎么寫,編寫SQL語句之后,DBMS對SQL語句進行執行,
最終來完成數據庫的數據管理。
1.4、安裝MySQL數據庫管理系統。
第一步:先安裝,選擇“經典版”
?第二步:需要進行MySQL數據庫實例配置。
注意:一路下一步就行了!!!!!
選擇安裝類型,有“Typical(默認)”、“Complete(完全)”、“Custom(用戶自定義)”三個選項,我們選
擇“Custom”,有更多的選項,也方便熟悉安裝過程
? 選擇服務器類型,“Developer Machine(開發測試類,mysql 占用很少資源)”、“Server
Machine(服務器類型,mysql 占用較多資源)”、“Dedicated MySQL Server Machine(專
門的數據庫服務器,mysql 占用所有可用資源)”,大家根據自己的類型選擇了,一般選
“Server Machine”,不會太少,也不會占滿
選擇 mysql 數據庫的大致用途,“Multifunctional Database(通用多功能型,能很好的支持 InnoDB 與
MyISAM 存儲引擎)”、“Transactional Database Only(服務器類型,專注于事務處理,一般)”、“Non-
Transactional Database Only(非事務處理型,較簡單,主要做一些監控、記數用,對 MyISAM 數據類型的
支持僅限于 non-transactional),隨自己的用途而選擇了,
需要注意的事項?
? 端口號:
? 端口號port是任何一個軟件/應用都會有的,端口號是應用的唯一代表。
? 端口號通常和IP地址在一塊,IP地址用來定位計算機的,端口號port是用來定位計算機上某個服務的/某個應用的!
? 在同一臺計算機上,端口號不能重復。具有唯一性。
? mysql數據庫啟動的時候,這個服務占有的默認端口號是3306;這是大家都知道的事兒。記住。
?
? 字符編碼方式?
? 設置mysql數據庫的字符編碼方式為 UTF8x`
? 一定要注意:先選中第3個單選按鈕,然后再選擇utf8字符集。
?
? 服務名稱?
? 默認是:MySQL;不用改。
?
? 選擇配置環境變量path:
? 如果沒有選擇怎么辦?你可以手動配置
? path=其它路徑;C:\Program Files (x86)\MySQL\MySQL Server 5.5\bin
?
? mysql超級管理員用戶名不能改,一定是:root
? 你需要設置mysql數據庫超級管理員的密碼。
? 我們設置為123456
? 設置密碼的同時,可以激活root賬戶遠程訪問。
? 激活:表示root賬號可以在外地登錄。
? 不激活:表示root賬號只能在本機上使用。
? 我這里選擇激活了!
1.4、MySQL數據庫的完美卸載!
? 第一步:雙擊安裝包進行卸載刪除。
? 第二步:刪除目錄:
? 把C:\ProgramData下面的MySQL目錄干掉。(隱藏文件)
? 把C:\Program Files (x86)下面的MySQL目錄干掉。
? 這樣就卸載結束了!
1.5、MySQL的服務
? 計算機–>右鍵–>管理–>服務和應用程序–>服務–>找mysql服務
? MySQL的服務,默認是“啟動”的狀態,只有啟動了mysql才能用。
? 默認情況下是“自動”啟動,自動啟動表示下一次重啟操作系統的時候自動啟動該服務。
可以在服務上點擊右鍵:
- 啟動
- 重啟服務
- 停止服務
- …
還可以改變服務的默認配置:
服務上點擊右鍵,屬性,然后可以選擇啟動方式:
- 自動(延遲啟動)
- 自動
- 手動
- 禁用
1.6、用命令來啟動和關閉mysql服務
? 語法:
- net stop 服務名稱;
- net start 服務名稱;
其它服務的啟停都可以采用以上的命令。
1.7、登錄mysql數據庫
使用bin目錄下的mysql.exe命令來連接mysql數據庫服務器
本地登錄(顯示編寫密碼的形式):
C:\Users\86178>mysql -uroot -p123456
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.36 MySQL Community Server (GPL)Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>
本地登錄(隱藏密碼的形式):
C:\Users\86178>mysql -uroot -p
Enter password: ******
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.5.36 MySQL Community Server (GPL)Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>
2、MySQL常用命令:
-
退出mysql :exit
-
查看mysql中有哪些數據庫?
show databases;
注意:以分號結尾,分號是英文的分號。
mysql默認自帶了4個數據庫。
-
怎么選擇使用某個數據庫呢?
mysql> use test;
- 怎么創建數據庫呢?
mysql> create database bjpowernode;
mysql> show databases;
- 查看某個數據庫下有哪些表?
mysql> use mysql;
mysql> show tables;
注意:以上的命令不區分大小寫,都行。
查看mysql數據庫的版本號:
mysql> select version();
查看當前使用的是哪個數據庫?
mysql> select database();
mysql> show
-> databases
-> ;
注意:mysql是不見“;”不執行,“;”表示終止一條語句!
mysql> show
->
->
->
->
->
->
->
->
-> \c
mysql>
注意:\c用來終止一條命令的輸入。
2.1、數據庫當中最基本的單元是:表
表(table)是一種結構化的文件,可以用來存儲特定類型的數據,如:學生信息,課程信息。
表都有特定的名稱,而且不能重復。
表中具有幾個概念:列、行、主鍵。
列叫做字段(Column),行叫做表中的記錄,
每一個字段都有:字段名稱/字段數據類型/字段約束/字段長度
數據庫當中是以表格的形式表示數據的;因為表比較直觀。
任何一張表都有行和列:
- 行(row):被稱為數據/記錄。
- 列(column):被稱為字段。
姓名字段、性別字段、年齡字段。
- 每一個字段都有:字段名、數據類型、約束等屬性。
- 字段名:是一個普通的名字,見名知意就行。
- 數據類型:字符串,數字,日期等,后期講。
- 約束:約束也有很多,其中一個叫做唯一性約束,這種約束添加之后,該字段中的數據不能重復。
2.2、關于SQL語句的分類?
SQL語句有很多,最好進行分門別類,這樣更容易記憶,分為:
-
DQL:數據查詢語言 (DQL-Data Query Language)
凡是帶有select關鍵字的都是查詢語句
select...
-
DML:數據操作語言 (DML-Data Manipulation Language)
凡是對表當中的數據進行增刪改的都是DML
? insert 增
? delete 刪
? update 改
? 注意:這個主要是操作表中的數據data。
-
DDL:數據定義語言 (DDL-Data Definition Language)
? DDL主要操作的是表的結構,不是表中的數據。
? create:新建,等同于增
? drop:刪除
? alter:修改? 注意:這個增刪改和DML不同,這個主要是對表結構進行操作。
-
TCL:事務控制語言 (TCL-Transactional Control Language)
? 事務提交:commit;
? 事務回滾:rollback,
-
DCL:是數據控制語言 (DCL-Data Control Language)
? 授權:grant
? 撤銷權限:revoke
2.3、導入一下提前準備好的數據:
使用 MySQL 命令行客戶端來裝載數據庫。
- 連接 MySql
mysql -uroot -p123456;
- 創建“bjpowernode”數據庫
mysql> create database bjpowernode;
- 選擇數據庫
mysql> use bjpowernode
- 導入數據
mysql>source D:\ bjpowernode.sql
- 刪除數據庫(這里不要做!)
mysql> drop database bjpowernode;
? 怎么將sql文件中的數據導入呢?
mysql> source D:\course\03-MySQL\document\bjpowernode.sql
注意:路徑中不要有中文!!!!
3、查看表結構
3.1**、查看和指定現有的數據庫**
mysql> show databases;
3.2**、指定當前缺省數據庫**
mysql> use bjpowernode;
3.3**、查看當前使用的庫**
mysql> select database();
3.4**、查看當前庫中的表**
mysql> show tables;
3.5**、查看其他庫中的表**
mysql> show tables from exam;
3.6**、查看表的結構**
mysql> desc emp;
mysql> show tables;
+-----------------------+
| Tables_in_bjpowernode |
+-----------------------+
| dept |
| emp |
| salgrade |
+-----------------------+
- dept是部門表
- emp是員工表
- salgrade 是工資等級表
怎么查看表中的數據呢?
? select * from 表名;
mysql> select * from emp;// 從emp表查詢所有數據。
+-------+--------+-----------+------+------------+---------+---------+--------+
| EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
+-------+--------+-----------+------+------------+---------+---------+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 | 1600.00 | 300.00 | 30 |
| 7521 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250.00 | 500.00 | 30 |
| 7566 | JONES | MANAGER | 7839 | 1981-04-02 | 2975.00 | NULL | 20 |
| 7654 | MARTIN | SALESMAN | 7698 | 1981-09-28 | 1250.00 | 1400.00 | 30 |
| 7698 | BLAKE | MANAGER | 7839 | 1981-05-01 | 2850.00 | NULL | 30 |
| 7782 | CLARK | MANAGER | 7839 | 1981-06-09 | 2450.00 | NULL | 10 |
| 7788 | SCOTT | ANALYST | 7566 | 1987-04-19 | 3000.00 | NULL | 20 |
| 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
| 7844 | TURNER | SALESMAN | 7698 | 1981-09-08 | 1500.00 | 0.00 | 30 |
| 7876 | ADAMS | CLERK | 7788 | 1987-05-23 | 1100.00 | NULL | 20 |
| 7900 | JAMES | CLERK | 7698 | 1981-12-03 | 950.00 | NULL | 30 |
| 7902 | FORD | ANALYST | 7566 | 1981-12-03 | 3000.00 | NULL | 20 |
| 7934 | MILLER | CLERK | 7782 | 1982-01-23 | 1300.00 | NULL | 10 |
+-------+--------+-----------+------+------------+---------+---------+--------+
mysql> select * from dept;
+--------+------------+----------+
| DEPTNO | DNAME | LOC |
+--------+------------+----------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
+--------+------------+----------+
mysql> select * from salgrade;
+-------+-------+-------+
| GRADE | LOSAL | HISAL |
+-------+-------+-------+
| 1 | 700 | 1200 |
| 2 | 1201 | 1400 |
| 3 | 1401 | 2000 |
| 4 | 2001 | 3000 |
| 5 | 3001 | 9999 |
+-------+-------+-------+
查看"演示數據"的表結構
不看表中的數據,只看表的結構,有一個命令:
mysql> desc 表名;
mysql> desc dept;+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| DEPTNO | int(2) | NO | PRI | NULL | |部門編號
| DNAME | varchar(14) | YES | | NULL | |部門名字
| LOC | varchar(13) | YES | | NULL | |地理位置
+--------+-------------+------+-----+---------+-------+
mysql> desc emp;
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| EMPNO | int(4) | NO | PRI | NULL | |員工編號
| ENAME | varchar(10) | YES | | NULL | |員工姓名
| JOB | varchar(9) | YES | | NULL | |工作崗位
| MGR | int(4) | YES | | NULL | |上級編號
| HIREDATE | date | YES | | NULL | |入職日期
| SAL | double(7,2) | YES | | NULL | |工資
| COMM | double(7,2) | YES | | NULL | |補助
| DEPTNO | int(2) | YES | | NULL | |部門編號
+----------+-------------+------+-----+---------+-------+
mysql> desc salgrade;
+-------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| GRADE | int(11) | YES | | NULL | |工資等級
| LOSAL | int(11) | YES | | NULL | |最低工資
| HISAL | int(11) | YES | | NULL | |最高工資
+-------+---------+------+-----+---------+-------+
describe縮寫為:desc
mysql> describe dept;
+--------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+-------------+------+-----+---------+-------+
| DEPTNO | int(2) | NO | PRI | NULL | |
| DNAME | varchar(14) | YES | | NULL | |
| LOC | varchar(13) | YES | | NULL | |
+--------+-------------+------+-----+---------+-------+
4、簡單查詢
4.1、查詢一個字段?
? select 字段名 from 表名;
?
其中要注意:
? **select和from都是關鍵字,字段名和表名都是標識符。**?
? 強調:
-
對于SQL語句來說,是通用的,
-
所有的SQL語句以“;”結尾。
-
另外SQL語句不區分大小寫,都行。
?查詢部門名字?
mysql> select dname from dept;
+------------+
| dname |
+------------+
| ACCOUNTING |
| RESEARCH |
| SALES |
| OPERATIONS |
+------------+
4 rows in set (0.00 sec)
?
mysql> SELECT DNAME FROM DEPT;
+------------+
| DNAME |
+------------+
| ACCOUNTING |
| RESEARCH |
| SALES |
| OPERATIONS |
+------------+
4 rows in set (0.00 sec)
4.2、查詢多個字段
? 使用逗號隔開“,”
? 查詢部門編號和部門名?
?
select deptno,dname from dept;
+--------+------------+
| deptno | dname |
+--------+------------+
| 10 | ACCOUNTING |
| 20 | RESEARCH |
| 30 | SALES |
| 40 | OPERATIONS |
+--------+------------+
4.3、查詢全部字段
- ? 第一種方式:可以把每個字段都寫上
? select a,b,c,d,e,f… from tablename; - ? 第二種方式:可以使用*
?
select * from dept;
+--------+------------+----------+
| DEPTNO | DNAME | LOC |
+--------+------------+----------+
| 10 | ACCOUNTING | NEW YORK |
| 20 | RESEARCH | DALLAS |
| 30 | SALES | CHICAGO |
| 40 | OPERATIONS | BOSTON |
+--------+------------+----------+
?
這種方式的缺點:
? 1、效率低
? 2、可讀性差。
? 在實際開發中不建議,可以自己玩沒問題。
? 你可以在DOS命令窗口中想快速的看一看全表數據可以采用這種方式。
4.4、給查詢的列起別名
mysql> select deptno,dname as deptname from dept;
? +--------+------------+
? | deptno | deptname |
? +--------+------------+
? | 10 | ACCOUNTING |
? | 20 | RESEARCH |
? | 30 | SALES |
? | 40 | OPERATIONS |
? +--------+------------+
? 使用as關鍵字起別名。
? 注意:只是將顯示的查詢結果列名顯示為deptname,原表列名還是叫:dname
? 記住:select語句是永遠都不會進行修改操作的。(因為只負責查詢)
? as關鍵字可以省略嗎?可以的
? mysql> select deptno,dname deptname from dept;
?
? 假設起別名的時候,別名里面有空格,怎么辦?
? mysql> select deptno,dname dept name from dept;
? DBMS看到這樣的語句,進行SQL語句的編譯,不符合語法,編譯報錯。
? 怎么解決?
?
select deptno,dname 'dept name' from dept; //加單引號
select deptno,dname "dept name" from dept; //加雙引號
+--------+------------+
| deptno | dept name |
+--------+------------+
| 10 | ACCOUNTING |
| 20 | RESEARCH |
| 30 | SALES |
| 40 | OPERATIONS |
+--------+------------+
? 注意:在所有的數據庫當中,字符串統一使用單引號括起來,
? 單引號是標準,雙引號在oracle數據庫中用不了。但是在mysql中可以使用。
? 再次強調:數據庫中的字符串都是采用單引號括起來。這是標準的。
? 雙引號不標準。
4.5、計算員工年薪?
mysql> select ename,sal from emp;
? +--------+---------+
? | ename | sal |
? +--------+---------+
? | SMITH | 800.00 |
? | ALLEN | 1600.00 |
? | WARD | 1250.00 |
? | JONES | 2975.00 |
? | MARTIN | 1250.00 |
? | BLAKE | 2850.00 |
? | CLARK | 2450.00 |
? | SCOTT | 3000.00 |
? | KING | 5000.00 |
? | TURNER | 1500.00 |
? | ADAMS | 1100.00 |
? | JAMES | 950.00 |
? | FORD | 3000.00 |
? | MILLER | 1300.00 |
? +--------+---------+
? 結論:字段可以使用數學表達式!
mysql> select ename,sal*12 from emp;
? +--------+----------+
? | ename | sal*12 |
? +--------+----------+
? | SMITH | 9600.00 |
? | ALLEN | 19200.00 |
? | WARD | 15000.00 |
? | JONES | 35700.00 |
? | MARTIN | 15000.00 |
? | BLAKE | 34200.00 |
? | CLARK | 29400.00 |
? | SCOTT | 36000.00 |
? | KING | 60000.00 |
? | TURNER | 18000.00 |
? | ADAMS | 13200.00 |
? | JAMES | 11400.00 |
? | FORD | 36000.00 |
? | MILLER | 15600.00 |
? +--------+----------+
起別名my
mysql> select ename,sal*12 as yearsal from emp;
? +--------+----------+
? | ename | yearsal |
? +--------+----------+
? | SMITH | 9600.00 |
? | ALLEN | 19200.00 |
? | WARD | 15000.00 |
? | JONES | 35700.00 |
? | MARTIN | 15000.00 |
? | BLAKE | 34200.00 |
? | CLARK | 29400.00 |
? | SCOTT | 36000.00 |
? | KING | 60000.00 |
? | TURNER | 18000.00 |
? | ADAMS | 13200.00 |
? | JAMES | 11400.00 |
? | FORD | 36000.00 |
? | MILLER | 15600.00 |
? +--------+----------+
? 別名是中文,用單引號括起來。
mysql> select ename,sal*12 as '年薪' from emp;
? +--------+----------+
? | ename | 年薪 |
? +--------+----------+
? | SMITH | 9600.00 |
? | ALLEN | 19200.00 |
? | WARD | 15000.00 |
? | JONES | 35700.00 |
? | MARTIN | 15000.00 |
? | BLAKE | 34200.00 |
? | CLARK | 29400.00 |
? | SCOTT | 36000.00 |
? | KING | 60000.00 |
? | TURNER | 18000.00 |
? | ADAMS | 13200.00 |
? | JAMES | 11400.00 |
? | FORD | 36000.00 |
? | MILLER | 15600.00 |
? +--------+----------+
5、條件查詢
5.1、什么是條件查詢?
? 不是將表中所有數據都查出來,是查詢出來符合條件的。
? 語法格式:
? select
? 字段1,字段2,字段3…
? from
? 表名
? where
? 條件;
5.2、都有哪些條件?
= 等于
查詢薪資等于800的員工姓名和編號?
select empno,ename from emp where sal = 800;
查詢SMIT的編號和薪資?
select empno,sal from emp where ename = 'SMITH'; //字符串使用單引號
<>或!= 不等于
查詢薪資不等于800的員工姓名和編號?
select empno,ename from emp where sal != 800;
select empno,ename from emp where sal <> 800; // 小于號和大于號組成的不等號
< 小于
查詢薪資小于2000的員工姓名和編號?
mysql> select empno,ename,sal from emp where sal < 2000;+-------+--------+---------+| empno | ename | sal |+-------+--------+---------+| 7369 | SMITH | 800.00 || 7499 | ALLEN | 1600.00 || 7521 | WARD | 1250.00 || 7654 | MARTIN | 1250.00 || 7844 | TURNER | 1500.00 || 7876 | ADAMS | 1100.00 || 7900 | JAMES | 950.00 || 7934 | MILLER | 1300.00 |+-------+--------+---------+
查詢薪資小于等于3000的員工姓名和編號?
select empno,ename,sal from emp where sal <= 3000;
大于
查詢薪資大于3000的員工姓名和編號?
select empno,ename,sal from emp where sal > 3000;
= 大于等于
查詢薪資大于等于3000的員工姓名和編號?
select empno,ename,sal from emp where sal >= 3000;
between … and …. 兩個值之間, 等同于 >= and <=
查詢薪資在2450和3000之間的員工信息?包括2450和3000
第一種方式:>= and <= (and是并且的意思。)
select empno,ename,sal from emp where sal >= 2450 and sal <= 3000;+-------+-------+---------+| empno | ename | sal |+-------+-------+---------+| 7566 | JONES | 2975.00 || 7698 | BLAKE | 2850.00 || 7782 | CLARK | 2450.00 || 7788 | SCOTT | 3000.00 || 7902 | FORD | 3000.00 |+-------+-------+---------+
? 第二種方式:between … and …
? select
? empno,ename,sal
? from
? emp
? where
? sal between 2450 and 3000;
?
? 注意:
- 使用between…and…的時候,必須遵循左小右大。
- between and是閉區間,包括兩端的值。
is null 為 null(is not null 不為空)
查詢哪些員工的津貼/補助為null?
mysql> select empno,ename,sal,comm from emp where comm = null;Empty set (0.00 sec)? mysql> select empno,ename,sal,comm from emp where comm is null;
? +-------+--------+---------+------+
? | empno | ename | sal | comm |
? +-------+--------+---------+------+
? | 7369 | SMITH | 800.00 | NULL |
? | 7566 | JONES | 2975.00 | NULL |
? | 7698 | BLAKE | 2850.00 | NULL |
? | 7782 | CLARK | 2450.00 | NULL |
? | 7788 | SCOTT | 3000.00 | NULL |
? | 7839 | KING | 5000.00 | NULL |
? | 7876 | ADAMS | 1100.00 | NULL |
? | 7900 | JAMES | 950.00 | NULL |
? | 7902 | FORD | 3000.00 | NULL |
? | 7934 | MILLER | 1300.00 | NULL |
? +-------+--------+---------+------+
? 10 rows in set (0.00 sec)
注意:在數據庫當中null不能使用等號進行衡量。需要使用is null
因為數據庫中的null代表什么也沒有,它不是一個值,所以不能使用等號衡量。
查詢哪些員工的津貼/補助不為null?
select empno,ename,sal,comm from emp where comm is not null;+-------+--------+---------+---------+| empno | ename | sal | comm |+-------+--------+---------+---------+| 7499 | ALLEN | 1600.00 | 300.00 || 7521 | WARD | 1250.00 | 500.00 || 7654 | MARTIN | 1250.00 | 1400.00 || 7844 | TURNER | 1500.00 | 0.00 |+-------+--------+---------+---------+
and 并且
查詢工作崗位是MANAGER并且工資大于2500的員工信息?
select empno,ename,job,sal
from emp
where job = 'MANAGER' and sal > 2500;
+-------+-------+---------+---------+
| empno | ename | job | sal |
+-------+-------+---------+---------+
| 7566 | JONES | MANAGER | 2975.00 |
| 7698 | BLAKE | MANAGER | 2850.00 |
+-------+-------+---------+---------+
or 或者
查詢工作崗位是MANAGER和SALESMAN的員工?
select empno,ename,job from emp where job = 'MANAGER';
select empno,ename,job from emp where job = 'SALESMAN';select empno,ename,job
fromemp
where job = 'MANAGER' or job = 'SALESMAN';? +-------+--------+----------+
? | empno | ename | job |
? +-------+--------+----------+
? | 7499 | ALLEN | SALESMAN |
? | 7521 | WARD | SALESMAN |
? | 7566 | JONES | MANAGER |
? | 7654 | MARTIN | SALESMAN |
? | 7698 | BLAKE | MANAGER |
? | 7782 | CLARK | MANAGER |
? | 7844 | TURNER | SALESMAN |
? +-------+--------+----------+
and和or同時出現的話,有優先級問題嗎?
查詢工資大于2500,并且部門編號為10或20部門的員工?
select *fromempwheresal > 2500 and deptno = 10 or deptno = 20;
? 分析以上語句的問題?
? and優先級比or高
? 以上語句會先執行and,然后執行or。
? 以上這個語句表示什么含義?
? 找出工資大于2500并且部門編號為10的員工,或者20部門所有員工找出來。
?
select *
fromemp
wheresal > 2500 and (deptno = 10 or deptno = 20);
and和or同時出現,and優先級較高。如果想讓or先執行,需要加“小括號”
以后在開發中,如果不確定優先級,就加小括號就行了。
in 包含
相當于多個 or (not in 不在這個范圍中)
查詢工作崗位是MANAGER和SALESMAN的員工?
select empno,ename,job from emp where job = 'MANAGER' or job = 'SALESMAN';
select empno,ename,job from emp where job in('MANAGER', 'SALESMAN');+-------+--------+----------+| empno | ename | job |+-------+--------+----------+| 7499 | ALLEN | SALESMAN || 7521 | WARD | SALESMAN || 7566 | JONES | MANAGER || 7654 | MARTIN | SALESMAN || 7698 | BLAKE | MANAGER || 7782 | CLARK | MANAGER || 7844 | TURNER | SALESMAN |+-------+--------+----------+
注意:in不是一個區間。in后面跟的是具體的值。
? 查詢薪資是800和5000的員工信息?
?
select ename,sal from emp where sal = 800 or sal = 5000;
select ename,sal from emp where sal in(800, 5000); //這個不是表示800到5000都找出來。
? +-------+---------+
? | ename | sal |
? +-------+---------+
? | SMITH | 800.00 |
? | KING | 5000.00 |
? +-------+---------+
?
select ename,sal from emp where sal in(800, 5000, 3000);
// not in 表示不在這幾個值當中的數據。
select ename,sal from emp where sal not in(800, 5000, 3000);
? +--------+---------+
? | ename | sal |
? +--------+---------+
? | ALLEN | 1600.00 |
? | WARD | 1250.00 |
? | JONES | 2975.00 |
? | MARTIN | 1250.00 |
? | BLAKE | 2850.00 |
? | CLARK | 2450.00 |
? | TURNER | 1500.00 |
? | ADAMS | 1100.00 |
? | JAMES | 950.00 |
? | MILLER | 1300.00 |
? +--------+---------+
not 可以取非,主要用在 is 或 in 中
- is null
- is not null
- in
- not in
**like **
稱為模糊查詢,支持%或下劃線匹配
- 百分號:任意多個字符
- 下劃線:任意一個字符
? (%是一個特殊的符號,_ 也是一個特殊符號)
? 找出名字中含有O的?
mysql> select ename from emp where ename like '%O%';
? +-------+
? | ename |
? +-------+
? | JONES |
? | SCOTT |
? | FORD |
? +-------+
? 找出名字以T結尾的?
select ename from emp where ename like '%T';
找出名字以K開始的?
select ename from emp where ename like 'K%';
? 找出第二個字每是A的?
select ename from emp where ename like '_A%';
? 找出第三個字母是R的?
select ename from emp where ename like '__R%';
? t_student學生表
? name字段
————————————————————————————
? zhangsan
? lisi
? wangwu
? zhaoliu
? jack_son
? 找出名字中有“_”的?
? \轉義字符
select name from t_student where name like '%_%'; //這樣不行。
mysql> select name from t_student where name like '%\_%'; // \轉義字符。
+----------+name |
+----------+
| jack_son |
+----------+
6、排序數據
6.1、單一字段排序
? 默認是升序!!!
select ename,sal
fromemp
order bysal;
+--------+---------+
| ename | sal |
+--------+---------+
| SMITH | 800.00 |
| JAMES | 950.00 |
| ADAMS | 1100.00 |
| WARD | 1250.00 |
| MARTIN | 1250.00 |
| MILLER | 1300.00 |
| TURNER | 1500.00 |
| ALLEN | 1600.00 |
| CLARK | 2450.00 |
| BLAKE | 2850.00 |
| JONES | 2975.00 |
| FORD | 3000.00 |
| SCOTT | 3000.00 |
| KING | 5000.00 |
+--------+---------+
6.2、手動指定排序順序
指定降序:
select ename,sal
fromemp
order bysal desc;+--------+---------+
| ename | sal |
+--------+---------+
| KING | 5000.00 |
| SCOTT | 3000.00 |
| FORD | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| ALLEN | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
| MARTIN | 1250.00 |
| WARD | 1250.00 |
| ADAMS | 1100.00 |
| JAMES | 950.00 |
| SMITH | 800.00 |
+--------+---------+
指定升序:
select ename,sal
fromemp
order bysal asc;+--------+---------+
| ename | sal |
+--------+---------+
| SMITH | 800.00 |
| JAMES | 950.00 |
| ADAMS | 1100.00 |
| WARD | 1250.00 |
| MARTIN | 1250.00 |
| MILLER | 1300.00 |
| TURNER | 1500.00 |
| ALLEN | 1600.00 |
| CLARK | 2450.00 |
| BLAKE | 2850.00 |
| JONES | 2975.00 |
| FORD | 3000.00 |
| SCOTT | 3000.00 |
| KING | 5000.00 |
+--------+---------+
6.3、多個字段排序
? 查詢員工名字和薪資,要求按照薪資升序,如果薪資一樣的話,再按照名字升序排列。
?
select ename,sal
fromemp
order bysal asc, ename asc; // sal在前字段,起主導,只有sal相等的時候,才會考慮啟用ename排序。+--------+---------+
| ename | sal |
+--------+---------+
| SMITH | 800.00 |
| JAMES | 950.00 |
| ADAMS | 1100.00 |
| MARTIN | 1250.00 |
| WARD | 1250.00 |
| MILLER | 1300.00 |
| TURNER | 1500.00 |
| ALLEN | 1600.00 |
| CLARK | 2450.00 |
| BLAKE | 2850.00 |
| JONES | 2975.00 |
| FORD | 3000.00 |
| SCOTT | 3000.00 |
| KING | 5000.00 |
+--------+---------+
6.4、根據字段的位置排序
使用字段的位置來排序
? select ename,sal from emp order by 2; // 2表示第二列。第二列是sal
? 按照查詢結果的第2列sal排序。
了解一下,不建議在開發中這樣寫,因為不健壯。
因為列的順序很容易發生改變,列順序修改之后,2就廢了。
6.5、綜合一點的案例:
? 找出工資在1250到3000之間的員工信息,要求按照薪資降序排列。
?
select ename,sal
fromemp
wheresal between 1250 and 3000
rder bysal desc;+--------+---------+
| ename | sal |
+--------+---------+
| FORD | 3000.00 |
| SCOTT | 3000.00 |
| JONES | 2975.00 |
| BLAKE | 2850.00 |
| CLARK | 2450.00 |
| ALLEN | 1600.00 |
| TURNER | 1500.00 |
| MILLER | 1300.00 |
| MARTIN | 1250.00 |
| WARD | 1250.00 |
+--------+---------+
?
關鍵字順序不能變:
- select
… - from
… - where
… - order by
…
以上語句的執行順序必須掌握:
- 第一步:from
- 第二步:where
- 第三步:select
- 第四步:order by(排序總是在最后執行!)
7、數據處理函數
數據處理函數又被稱為單行處理函數
單行處理函數的特點:一個輸入對應一個輸出。
和單行處理函數相對的是:多行處理函數。(多行處理函數特點:多個輸入,對應一個輸出!)
單行處理函數常見的有哪些?
lower 轉換小寫
mysql> select lower(ename) as ename from emp;+--------+| ename |+--------+| smith || allen || ward || jones || martin || blake || clark || scott || king || turner || adams || james || ford || miller |+--------+
? 14個輸入,最后還是14個輸出。這是單行處理函數的特點。
upper 轉換大寫
mysql> select * from t_student;+----------+| name |+----------+| zhangsan || lisi || wangwu || jack_son |+----------+mysql> select upper(name) as name from t_student;
? +----------+
? | name |
? +----------+
? | ZHANGSAN |
? | LISI |
? | WANGWU |
? | JACK_SON |
? +----------+
substr 取子串
(substr( 被截取的字符串, 起始下標,截取的長度))
select substr(ename, 1, 1) as ename from emp;
? 注意:起始下標從1開始,沒有0.
? 找出員工名字第一個字母是A的員工信息?
? 第一種方式:模糊查詢
select ename from emp where ename like 'A%';
? 第二種方式:substr函數
? select
? ename
? from
? emp
? where
? substr(ename,1,1) = ‘A’;
? 首字母大寫?
?
select name from t_student;
select upper(substr(name,1,1)) from t_student;
select substr(name,2,length(name) - 1) from t_student;select concat(upper(substr(name,1,1)),substr(name,2,length(name) - 1)) as result from t_student;
? +----------+
? | result |
? +----------+
? | Zhangsan |
? | Lisi |
? | Wangwu |
? | Jack_son |
? +----------+
concat函數進行字符串的拼接
?
select concat(empno,ename) from emp;
? +---------------------+
? | concat(empno,ename) |
? +---------------------+
? | 7369SMITH |
? | 7499ALLEN |
? | 7521WARD |
? | 7566JONES |
? | 7654MARTIN |
? | 7698BLAKE |
? | 7782CLARK |
? | 7788SCOTT |
? | 7839KING |
? | 7844TURNER |
? | 7876ADAMS |
? | 7900JAMES |
? | 7902FORD |
? | 7934MILLER |
? +---------------------+
length 取長度
select length(ename) as enamelength from emp;+-------------+| enamelength |+-------------+| 5 || 5 || 4 || 5 || 6 || 5 || 5 || 5 || 4 || 6 || 5 || 5 || 4 || 6 |+-------------+
trim 會去首尾空格,不會去除中間的空格
mysql> select * from emp where ename = ' KING';Empty set (0.00 sec)mysql> select * from emp where ename = trim(' KING');
? +-------+-------+-----------+------+------------+---------+------+--------+
? | EMPNO | ENAME | JOB | MGR | HIREDATE | SAL | COMM | DEPTNO |
? +-------+-------+-----------+------+------------+---------+------+--------+
? | 7839 | KING | PRESIDENT | NULL | 1981-11-17 | 5000.00 | NULL | 10 |
? +-------+-------+-----------+------+------------+---------+------+--------+
str_to_date 將字符串轉換成日期
查詢 1981-02-20 入職的員工(第一種方法,與數據庫的格式匹配上)
select * from emp where HIREDATE='1981-02-20';
查詢 1981-02-20 入職的員工(第二種方法,將字符串轉換成 date 類型)
select * from emp where HIREDATE=str_to_date('1981-02-20','%Y-%m-%d');
select * from emp where HIREDATE=str_to_date('02-20-1981','%m-%d-%Y');
date_format 格式化日期
查詢 1981-02-20 以后入職的員工,將入職日期格式化成 yyyy-mm-dd hh:mm:ss
select empno, ename, date_format(hiredate, '%Y-%m-%d %H:%i:%s') as hiredate from emp;
select date_format(now(),'%Y-%m-%d %H %i %s');
now() 獲得當前時間
日期格式的說明
%Y:代表 4 位的年份
%y:代表 2 位的年份
%m:代表月, 格式為(01……12)
%c:代表月, 格式為(1……12)
%H:代表小時,格式為(00……23)
%h: 代表小時,格式為(01……12)
%i: 代表分鐘, 格式為(00……59)
%r:代表 時間,格式為 12 小時(hh:mm:ss [AP]M)
%T:代表 時間,格式為 24 小時(hh:mm:ss)
%S:代表 秒,格式為(00……59)
%s:代表秒,格式為(00……59)
format 設置千分位
查詢員工薪水加入千分位
select empno, ename, Format(sal, 0) from emp;
查詢員工薪水加入千分位和保留兩位小數
select empno, ename, Format(sal, 2) from emp;
case…when…then…when…then…else…end (else正常的字段)
當員工的工作崗位是MANAGER的時候,工資上調10%,當工作崗位是SALESMAN的時候,工資上調50%,其它正常。
? **(注意:不修改數據庫,只是將查詢結果顯示為工資上調)
**
select ename,job, sal as oldsal,
(case job when 'MANAGER' then sal*1.1 when 'SALESMAN' then sal*1.5 else sal end) as newsal
from emp;+--------+-----------+---------+---------+
| ename | job | oldsal | newsal |
+--------+-----------+---------+---------+
| SMITH | CLERK | 800.00 | 800.00 |
| ALLEN | SALESMAN | 1600.00 | 2400.00 |
| WARD | SALESMAN | 1250.00 | 1875.00 |
| JONES | MANAGER | 2975.00 | 3272.50 |
| MARTIN | SALESMAN | 1250.00 | 1875.00 |
| BLAKE | MANAGER | 2850.00 | 3135.00 |
| CLARK | MANAGER | 2450.00 | 2695.00 |
| SCOTT | ANALYST | 3000.00 | 3000.00 |
| KING | PRESIDENT | 5000.00 | 5000.00 |
| TURNER | SALESMAN | 1500.00 | 2250.00 |
| ADAMS | CLERK | 1100.00 | 1100.00 |
| JAMES | CLERK | 950.00 | 950.00 |
| FORD | ANALYST | 3000.00 | 3000.00 |
| MILLER | CLERK | 1300.00 | 1300.00 |
+--------+-----------+---------+---------+
round 四舍五入
? select 字段 from 表名;
?
select ename from emp;
select 'abc' from emp; // select后面直接跟“字面量/字面值”mysql> select 'abc' as bieming from emp;
? +---------+
? | bieming |
? +---------+
? | abc |
? | abc |
? | abc |
? | abc |
? | abc |
? | abc |
? | abc |
? | abc |
? | abc |
? | abc |
? | abc |
? | abc |
? | abc |
? | abc |
? +---------+
?
mysql> select abc from emp;
ERROR 1054 (42S22): Unknown column 'abc' in 'field list'
? 這樣肯定報錯,因為會把abc當做一個字段的名字,去emp表中找abc字段去了。
?
select 1000 as num from emp; // 1000 也是被當做一個字面量/字面值。
? +------+
? | num |
? +------+
? | 1000 |
? | 1000 |
? | 1000 |
? | 1000 |
? | 1000 |
? | 1000 |
? | 1000 |
? | 1000 |
? | 1000 |
? | 1000 |
? | 1000 |
? | 1000 |
? | 1000 |
? | 1000 |
? +------+
? **結論:select后面可以跟某個表的字段名(可以等同看做變量名),也可以跟字面量/字面值(數據)。
**?
select 21000 as num from dept;
? +-------+
? | num |
? +-------+
? | 21000 |
? | 21000 |
? | 21000 |
? | 21000 |
? +-------+
?
mysql> select round(1236.567, 0) as result from emp; //保留整數位。
? +--------+
? | result |
? +--------+
? | 1237 |
? | 1237 |
? | 1237 |
? | 1237 |
? | 1237 |
? | 1237 |
? | 1237 |
? | 1237 |
? | 1237 |
? | 1237 |
? | 1237 |
? | 1237 |
? | 1237 |
? | 1237 |
? +--------+
?
select round(1236.567, 1) as result from emp; //保留1個小數
select round(1236.567, 2) as result from emp; //保留2個小數
select round(1236.567, -1) as result from emp; // 保留到十位。
? +--------+
? | result |
? +--------+
? | 1240 |
? | 1240 |
? | 1240 |
? | 1240 |
? | 1240 |
? | 1240 |
? | 1240 |
? | 1240 |
? | 1240 |
? | 1240 |
? | 1240 |
? | 1240 |
? | 1240 |
? | 1240 |
? +--------+
?
select round(1236.567, -2) as result from emp;
? +--------+
? | result |
? +--------+
? | 1200 |
? | 1200 |
? | 1200 |
? | 1200 |
? | 1200 |
? | 1200 |
? | 1200 |
? | 1200 |
? | 1200 |
? | 1200 |
? | 1200 |
? | 1200 |
? | 1200 |
? | 1200 |
? +--------+
rand() 生成隨機數
mysql> select round(rand()*100,0) from emp; // 100以內的隨機數+---------------------+| round(rand()*100,0) |+---------------------+| 76 || 29 || 15 || 88 || 95 || 9 || 63 || 89 || 54 || 3 || 54 || 61 || 42 || 28 |+---------------------+
ifnull
可以將 null 轉換成一個具體值
? ifnull是空處理函數。專門處理空的。
? 在所有數據庫當中,只要有NULL參與的數學運算,最終結果就是NULL。
mysql> select ename, sal + comm as salcomm from emp;+--------+---------+| ename | salcomm |+--------+---------+| SMITH | NULL || ALLEN | 1900.00 || WARD | 1750.00 || JONES | NULL || MARTIN | 2650.00 || BLAKE | NULL || CLARK | NULL || SCOTT | NULL || KING | NULL || TURNER | 1500.00 || ADAMS | NULL || JAMES | NULL || FORD | NULL || MILLER | NULL |+--------+---------+
? 計算每個員工的年薪?
? 年薪 = (月薪 + 月補助) * 12
select ename, (sal + comm) * 12 as yearsal from emp;
? +--------+----------+
? | ename | yearsal |
? +--------+----------+
? | SMITH | NULL |
? | ALLEN | 22800.00 |
? | WARD | 21000.00 |
? | JONES | NULL |
? | MARTIN | 31800.00 |
? | BLAKE | NULL |
? | CLARK | NULL |
? | SCOTT | NULL |
? | KING | NULL |
? | TURNER | 18000.00 |
? | ADAMS | NULL |
? | JAMES | NULL |
? | FORD | NULL |
? | MILLER | NULL |
? +--------+----------+
? 注意:NULL只要參與運算,最終結果一定是NULL。為了避免這個現象,需要使用ifnull函數。
? ifnull函數用法:ifnull(數據, 被當做哪個值)
? 如果“數據”為NULL的時候,把這個數據結構當做哪個值。
?
? 補助為NULL的時候,將補助當做0
?
select ename, (sal + ifnull(comm, 0)) * 12 as yearsal from emp;
? +--------+----------+
? | ename | yearsal |
? +--------+----------+
? | SMITH | 9600.00 |
? | ALLEN | 22800.00 |
? | WARD | 21000.00 |
? | JONES | 35700.00 |
? | MARTIN | 31800.00 |
? | BLAKE | 34200.00 |
? | CLARK | 29400s.00 |
? | SCOTT | 36000.00 |
? | KING | 60000.00 |
? | TURNER | 18000.00 |
? | ADAMS | 13200.00 |
? | JAMES | 11400.00 |
? | FORD | 36000.00 |
? | MILLER | 15600.00 |
? +--------+----------+
8、分組函數(多行處理函數)
?
多行處理函數的特點:輸入多行,最終輸出一行。
5個:
- count 計數
- sum 求和
- avg 平均值
- max 最大值
- min 最小值
注意:
- 分組函數在使用的時候必須先進行分組,然后才能用。
- 如果你沒有對數據進行分組,整張表默認為一組。
找出最高工資?
mysql> select max(sal) from emp;
+----------+
| max(sal) |
+----------+
| 5000.00 |
+----------+
找出最低工資?
mysql> select min(sal) from emp;
+----------+
| min(sal) |
+----------+
| 800.00 |
+----------+
計算工資和:
mysql> select sum(sal) from emp;
+----------+
| sum(sal) |
+----------+
| 29025.00 |
+----------+
計算平均工資:
mysql> select avg(sal) from emp;
+-------------+
| avg(sal) |
+-------------+
| 2073.214286 |
+-------------+
? 14個工資全部加起來,然后除以14。
計算員工數量?
mysql> select count(ename) from emp;
+--------------+
| count(ename) |
+--------------+
| 14 |
+--------------+
分組函數在使用的時候需要注意哪些?
? **第一點:分組函數自動忽略NULL,你不需要提前對NULL進行處理。**?
mysql> select sum(comm) from emp;
? +-----------+
? | sum(comm) |
? +-----------+
? | 2200.00 |
? +-----------+
mysql> select count(comm) from emp;
? +-------------+
? | count(comm) |
? +-------------+
? | 4 |
? +-------------+
mysql> select avg(comm) from emp;
? +------------+
? | avg(comm) |
? +------------+
? | 550.000000 |
? +------------+
? **第二點:分組函數中count(*)和count(具體字段)有什么區別?
**?
mysql> select count(*) from emp;
? +----------+
? | count(*) |
? +----------+
? | 14 |
? +----------+
?
mysql> select count(comm) from emp;
? +-------------+
? | count(comm) |
? +-------------+
? | 4 |
? +-------------+
?
- count(具體字段):表示統計該字段下所有不為NULL的元素的總數。
- count(*):統計表當中的總行數。(只要有一行數據count則++)
因為每一行記錄不可能都為NULL,一行數據中有一列不為NULL,則這行數據就是有效的。
?
?第三點:分組函數不能夠直接使用在where子句中。
? 找出比最低工資高的員工信息。
select ename,sal from emp where sal > min(sal);
? 表面上沒問題,運行一下?
ERROR 1111 (HY000): Invalid use of group function
? 說完分組查詢(group by)之后就明白了了。
第四點:所有的分組函數可以組合起來一起用。
select sum(sal),min(sal),max(sal),avg(sal),count(*) from emp;
+----------+----------+----------+-------------+----------+
| sum(sal) | min(sal) | max(sal) | avg(sal) | count(*) |
+----------+----------+----------+-------------+----------+
| 29025.00 | 800.00 | 5000.00 | 2073.214286 | 14 |
+----------+----------+----------+-------------+----------+
9、分組查詢(非常重要:五顆星)
?
9.1、什么是分組查詢?
? 在實際的應用中,可能有這樣的需求,需要先進行分組,然后對每一組的數據進行操作。
? 這個時候我們需要使用分組查詢,怎么進行分組查詢呢?
? select
? …
? from
? …
? group by
? …
?
? 計算每個部門的工資和?
? 計算每個工作崗位的平均薪資?
? 找出每個工作崗位的最高薪資?
? …
9.2、將之前的關鍵字全部組合在一起,來看一下他們的執行順序?
? select
? …
? from
? …
? where
? …
? group by
? …
? order by
? …
?
? 以上關鍵字的順序不能顛倒,需要記憶。
? 執行順序是什么?
- from
- where
- group by
- select
- order by
為什么分組函數不能直接使用在where后面?
select ename,sal from emp where sal > min(sal);//報錯。
? 因為分組函數在使用的時候必須先分組之后才能使用。
? where執行的時候,還沒有分組。所以where后面不能出現分組函數(5個)。
select sum(sal) from emp;
? 這個沒有分組,為啥sum()函數可以用呢?
? **因為select在group by之后執行,所以select后面可以使用分組函數
**
9.3、找出每個工作崗位的工資和?
? 實現思路:按照工作崗位分組,然后對工資求和。
?
select job,sum(sal)
fromemp
group byjob;+-----------+----------+
| job | sum(sal) |
+-----------+----------+
| ANALYST | 6000.00 |
| CLERK | 4150.00 |
| MANAGER | 8275.00 |
| PRESIDENT | 5000.00 |
| SALESMAN | 5600.00 |
+-----------+----------+
? 以上這個語句的執行順序?
? 先從emp表中查詢數據。
? 根據job字段進行分組。
? 然后對每一組的數據進行sum(sal)
?
?
select ename,job,sum(sal) from emp group by job;
? +-------+-----------+----------+
? | ename | job | sum(sal) |
? +-------+-----------+----------+
? | SCOTT | ANALYST | 6000.00 |
? | SMITH | CLERK | 4150.00 |
? | JONES | MANAGER | 8275.00 |
? | KING | PRESIDENT | 5000.00 |
? | ALLEN | SALESMAN | 5600.00 |
? +-------+-----------+----------+
? 以上語句在mysql中可以執行,但是毫無意義。
? 以上語句在oracle中執行報錯。
? oracle的語法比mysql的語法嚴格。(mysql的語法相對來說松散一些!)
? 重點結論:
? 在一條select語句當中,如果有group by語句的話,?select后面只能跟:參加分組的字段,以及分組函數(5個)。其它的一律不能跟。
? 在 SQL 語句中若有 group by 語句,那么在 select 語句后面只能跟分組函數+參與分組的字段。
9.4、找出每個部門的最高薪資
? 實現思路是什么?
? 按照部門編號分組,求每一組的最大值。
? **select后面添加ename字段沒有意義,另外oracle會報錯。
**?
mysql> select ename,deptno,max(sal) from emp group by deptno;
? +-------+--------+----------+
? | ename | deptno | max(sal) |
? +-------+--------+----------+
? | CLARK | 10 | 5000.00 |
? | SMITH | 20 | 3000.00 |
? | ALLEN | 30 | 2850.00 |
? +-------+--------+----------+
?
mysql> select deptno,max(sal) from emp group by deptno;
? +--------+----------+
? | deptno | max(sal) |
? +--------+----------+
? | 10 | 5000.00 |
? | 20 | 3000.00 |
? | 30 | 2850.00 |
? +--------+----------+
9.5、找出“每個部門,不同工作崗位”的最高薪資?
+--------+-----------+---------+--------+
? | ename | job | sal | deptno |
? +--------+-----------+---------+--------+
? | MILLER | CLERK | 1300.00 | 10 |
? | KING | PRESIDENT | 5000.00 | 10 |
? | CLARK | MANAGER | 2450.00 | 10 |? | FORD | ANALYST | 3000.00 | 20 |
? | ADAMS | CLERK | 1100.00 | 20 |
? | SCOTT | ANALYST | 3000.00 | 20 |
? | JONES | MANAGER | 2975.00 | 20 |
? | SMITH | CLERK | 800.00 | 20 |? | BLAKE | MANAGER | 2850.00 | 30 |
? | MARTIN | SALESMAN | 1250.00 | 30 |
? | ALLEN | SALESMAN | 1600.00 | 30 |
? | TURNER | SALESMAN | 1500.00 | 30 |
? | WARD | SALESMAN | 1250.00 | 30 |
? | JAMES | CLERK | 950.00 | 30 |
? +--------+-----------+---------+--------+
? **技巧:兩個字段聯合成1個字段看。(兩個字段聯合分組)
**?
select
? deptno, job, max(sal)
? from
? emp
? group by
? deptno, job;? +--------+-----------+----------+
? | deptno | job | max(sal) |
? +--------+-----------+----------+
? | 10 | CLERK | 1300.00 |
? | 10 | MANAGER | 2450.00 |
? | 10 | PRESIDENT | 5000.00 |
? | 20 | ANALYST | 3000.00 |
? | 20 | CLERK | 1100.00 |
? | 20 | MANAGER | 2975.00 |
? | 30 | CLERK | 950.00 |
? | 30 | MANAGER | 2850.00 |
? | 30 | SALESMAN | 1600.00 |
? +--------+-----------+----------+
9.6、having
having不能單獨使用,having不能代替where單獨使用,having必須和group by聯合使用。
使用having可以對分完組之后的數據進一步過濾。
找出每個部門最高薪資,要求顯示最高薪資大于3000的?
? 第一步:找出每個部門最高薪資
? 按照部門編號分組,求每一組最大值。
select deptno,max(sal) from emp group by deptno;
? +--------+----------+
? | deptno | max(sal) |
? +--------+----------+
? | 10 | 5000.00 |
? | 20 | 3000.00 |
? | 30 | 2850.00 |
? +--------+----------+
? 第二步:要求顯示最高薪資大于3000
?
select
? deptno,max(sal)
? from
? emp
? group by
? deptno
? having
? max(sal) > 3000;? +--------+----------+
? | deptno | max(sal) |
? +--------+----------+
? | 10 | 5000.00 |
? +--------+----------+
? 思考一個問題:以上的sql語句執行效率是不是低?
? 比較低,實際上可以這樣考慮:先將大于3000的都找出來,然后再分組。
?
select
? deptno,max(sal)
? from
? emp
? where
? sal > 3000
? group by
? deptno;
?
? +--------+----------+
? | deptno | max(sal) |
? +--------+----------+
? | 10 | 5000.00 |
? +--------+----------+
where先篩選后分組,having先分組在篩選
**優化策略:where和having,優先選擇where,where實在完成不了了,再選擇having。
**
9.7、where沒辦法的
? 找出每個部門平均薪資,要求顯示平均薪資高于2500的。
? 第一步:找出每個部門平均薪資
?
select deptno,avg(sal) from emp group by deptno;
? +--------+-------------+
? | deptno | avg(sal) |
? +--------+-------------+
? | 10 | 2916.666667 |
? | 20 | 2175.000000 |
? | 30 | 1566.666667 |
? +--------+-------------+
? 第二步:要求顯示平均薪資高于2500的
?
select
? deptno,avg(sal)
? from
? emp
? group by
? deptno
? having
? avg(sal) > 2500;
?
? +--------+-------------+
? | deptno | avg(sal) |
? +--------+-------------+
? | 10 | 2916.666667 |
? +--------+-------------+
9.8、大總結(單表的查詢)
? select
? …
? from
? …
? where
? …
? group by
? …
? having (就是為了過濾分組后的數據而存在的—不可以單獨的出現)
? …
? order by
? …
?
以上關鍵字只能按照這個順序來,不能顛倒。
執行順序?
-
from
-
where 過濾原始數據
-
group by 進行分組
-
having 對分組數據進行過濾
-
select 選出數據
-
order by 排序輸出
從某張表中查詢數據,
先經過where條件篩選出有價值的數據。
對這些有價值的數據進行分組。
分組之后可以使用having繼續篩選。
select查詢出來。
最后排序輸出!
原則:能在 where 中過濾的數據,盡量在 where 中過濾,效率較高。
having 的過濾是專門對分組之后的數據進行過濾的。
找出每個崗位的平均薪資,要求顯示平均薪資大于1500的,除MANAGER崗位之外,要求按照平均薪資降序排。
select job, avg(sal) as avgsalfromempwherejob <> 'MANAGER'group byjobhavingavg(sal) > 1500order byavgsal desc;? +-----------+-------------+
? | job | avgsal |
? +-----------+-------------+
? | PRESIDENT | 5000.000000 |
? | ANALYST | 3000.000000 |
? +-----------+-------------+
order by為什么可以使用avgsal?是因為先執行select后執行order by。
逗號的使用:字段與字段之間,調用函數當中的值
?
? 假設有一條非常復雜的SQL語句,而這條SQL語句需要在不同的位置上反復使用。
? 每一次使用這個sql語句的時候都需要重新編寫,很長,很麻煩,怎么辦?
? 可以把這條復雜的SQL語句以視圖對象的形式新建。
? 在需要編寫這條SQL語句的位置直接使用視圖對象,可以大大簡化開發。
? 并且利于后期的維護,因為修改的時候也只需要修改一個位置就行,只需要修改視圖對象所映射的SQL語句。
?
? 我們以后面向視圖開發的時候,使用視圖的時候可以像使用table一樣。
? 可以對視圖進行增刪改查等操作。視圖不是在內存當中,視圖對象也是存儲在硬盤上的,不會消失。
再提醒一下:
? 視圖對應的語句只能是DQL查詢語句。
? 但是視圖對象創建完成之后,可以對視圖進行增刪改查等操作。
? 小插曲:
? 增刪改查,又叫做:CRUD。
? CRUD是在公司中程序員之間溝通的術語。一般我們很少說增刪改查。
? 一般都說CRUD。
? C:Create(增)
? R:Retrive(查:檢索)
? U:Update(改)
? D:Delete(刪)