1. 程式人生 > >mysql章節(二)(MySQL的事務與儲存精講)

mysql章節(二)(MySQL的事務與儲存精講)

/豪華的分割線*********/
– DQL(資料庫查詢語句),專門從資料庫表表查詢相關資料的
/*
查詢語句的語法
SELECT 欄位列表
FROM 表名;

在cmd視窗中,SQL語句的末尾必須要用分號結束
但是在視窗客戶端中,SQL語句的末尾可有有分號,也可以沒有分號,為了語句的完整,語句末尾加上分號
SQL語句不區分大小寫
*/


– 從表中出現單個的欄位
SELECT EMPNO
FROM EMP;

select empno
from emp;


– 從表中出現多個欄位,多個欄位之間使用逗號分隔,最後一個欄位後面沒有逗號
SELECT EMPNO,ENAME,JOB,HIREDATE
FROM EMP;


– 從表中查詢全部的欄位
SELECT EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO
FROM EMP;

– 查詢全部欄位的時候,可以用* 來替代查詢列表.但是為了程式碼的可讀性,最好還是寫清楚欄位列表,也就是上面的方式
SELECT *
FROM EMP;

DESC EMP;


– 在查詢列表中可以使用算術表示式
– 查詢員工的年薪(年薪 = SAL * 12)
SELECT EMPNO,ENAME ,SAL ,SAL*12
FROM EMP;


– 我們可以給查詢欄位起別名
– 起別名的時候可以使用AS,也可以不使用AS;可以使用"",也可以使用’’,也可以不使用引號
SELECT EMPNO AS “員工編號”,ENAME “員工姓名”,SAL ‘月薪’,SAL*12 年薪
FROM EMP;

/豪華的分割線*********/
– 條件查詢語句,也就是在查詢語句中加入適當的條件,只有滿足查詢條件的結果才會被顯示
– 條件查詢語句需要使用WHERE子句;(什麼是子句,也就是可有可無的語句)
/*
條件查詢語句的語法
SELECT 欄位列表
FROM 表明
[WHERE 查詢條件]

語句執行的順序:
1.SELECT FROM 查詢出全部的資料
2.使用WHERE對資料進行過濾
*/

– 資料庫中的三種主要型別
– 1.字元型,可以表示一個或多個字元
– 2.數值型,可以有小數,也可以沒有小數
– 3,日期型,表示日期型的資料
– 注意:在資料庫中使用字元型資料和日期型資料的時候,必須要使用""或’’


– 1.使用=作為查詢條件,適用於資料庫中的三種主要類

– 查詢員工名字是"SMITH"的員工資訊
SELECT *
FROM EMP
WHERE ENAME = “SMITH”;

SELECT *
FROM EMP
WHERE ENAME = ‘SMITH’;

– 查詢職位是"MANAGER"的員工資訊
SELECT *
FROM EMP
WHERE JOB = “MANAGER”;

– 查詢員工編號7566的資訊
SELECT *
FROM EMP
WHERE EMPNO = 7566;

– 查詢僱傭日期是"1981-02-22"的員工資訊
SELECT *
FROM EMP
WHERE HIREDATE = “1981-02-22”;


– SQL語句不區分大小寫,但是表中的字元型的資料是區分大小寫的
– (1)Oracle在任何的平臺上都是嚴格區分字元型資料大小寫的
– (2)MySql在Linux/Unix平臺上是嚴格區分字元型資料大小寫的
– (3)MySql在Window平臺上不區分字元型資料的大小寫
SELECT *
FROM EMP
WHERE ENAME = ‘SMITH’;

SELECT *
FROM EMP
WHERE ENAME = ‘smith’;

– 我們如何讓MySql在Window平臺上也嚴格的區分字元型資料的大小寫呢,可以使用binary關鍵字
SELECT *
FROM EMP
WHERE BINARY ENAME = ‘smith’;


– 2,使用<> 或 != 作為查詢條件,適用於三種主要型別

– 查詢名字不是"SMITH"的員工資訊
SELECT *
FROM EMP
WHERE ENAME <> “SMITH”;

SELECT *
FROM EMP
WHERE ENAME != “SMITH”;

– 查詢工資不是3000的員工資訊
SELECT *
FROM EMP
WHERE SAL <> 3000;

– 查詢僱傭日期不是"1981-02-22"的員工資訊
SELECT *
FROM EMP
WHERE HIREDATE != “1981-02-22”;


– 3.使用 <,<=,>,>=作為查詢條件

– 查詢工資大於等於3000的員工的資訊
SELECT *
FROM EMP
WHERE SAL >= 3000;

SELECT *
FROM EMP
WHERE SAL > 3000;

SELECT *
FROM EMP
WHERE SAL <= 3000;

SELECT *
FROM EMP
WHERE SAL < 3000;


– 4.使用BETWEEN AND 作為查詢條件,在特定的範圍之內

– (1)BETWEEN AND 作用於數值型的資料和日期型的資料的時候,是包含兩個邊界值的
– 查詢工資在1600~3000之間的員工資訊
SELECT *
FROM EMP
WHERE SAL BETWEEN 1600 AND 3000;

– BETWEEN AND的功能也可以使用AND來完成
SELECT *
FROM EMP
WHERE SAL >= 1600 AND SAL <=3000;

– 查詢僱傭日期在"1981-02-20"~"1981-12-03"的員工資訊
SELECT *
FROM EMP
WHERE HIREDATE BETWEEN “1981-02-20” AND “1981-12-03”;

– (2)BETWEEN AND 對於字元型的資料比較特殊,包含第一個值,但是不包含第二個值
– 查詢名字從A~F之間的員工資訊
SELECT *
FROM EMP
WHERE ENAME BETWEEN “A” AND “F”;

– 所以需要查詢"A"~“F"的員工,正確的語句如下
– MySql中的字元編碼也是採用Unicode的,我們要查詢"A”~"Z"的員工,找"Z"的下一個字元即可
SELECT *
FROM EMP
WHERE ENAME BETWEEN “A” AND “G”;

– 查詢工資在1600~3000之間的員工資訊


– 5.使用IS NULL作為查詢條件
– NULL是資料庫中一種特殊的資料,表示沒有資料;三種主要型別都支援NULL
– 對於NULL的判斷,不能使用=;而是需要使用 IS NULL進行判斷

– 查詢津貼(COMM)是NULL的員工
– 對於NULL的判斷,不能使用=;下面的語句查詢不到資料
SELECT *
FROM EMP
WHERE COMM = NULL;

– 而是需要使用 IS NULL進行判斷
SELECT *
FROM EMP
WHERE COMM IS NULL;

– 查詢津貼不為NULL的員工資訊
SELECT *
FROM EMP
WHERE COMM IS NOT NULL;


– 6,使用AND連線多個查詢條件; 要求多個查詢條件必須要同時成立,相當於Java中的&& ,也就是並且的意思

– 查詢工資大於1600 並且部門編號是20的員工資訊
SELECT *
FROM EMP
WHERE SAL >1600 AND DEPTNO = 20;

– AND 也可以使用 && 來代替
SELECT *
FROM EMP
WHERE SAL >1600 && DEPTNO = 20;


– 7.使用OR連線多個查詢條件,多個查詢條件中只有滿足任一個條件即可,相當於Java中的 || ,也就是或者的意思

– 查詢工資大於1600 或者部門編號是20的員工資訊
SELECT *
FROM EMP
WHERE SAL > 1600 OR DEPTNO = 20;

– OR也可以使用|| 來代替
SELECT *
FROM EMP
WHERE SAL > 1600 || DEPTNO = 20;

– 查詢部門編號是20 或部門編號是30的員工資訊
SELECT *
FROM EMP
WHERE DEPTNO=20 || DEPTNO = 30;


– 8.注意:AND 和 OR是有優先順序的,首先要執行AND ,後執行OR [這個順序必須要記住]
– 為了語法的清晰,把不同的條件用()擴起來

– 查詢薪水大於1800,並且部門編號為20或30的員工
SELECT *
FROM EMP
WHERE SAL > 1800 AND DEPTNO = 20 OR DEPTNO = 30;

– 仔細分析上面的查詢條件,工資大於1600是一個條件;部門編號為20或30是另一個條件,兩個條件要同時成立
– 上面語句的查詢結果時錯誤的,這是因為首先執行的是and,後執行的是or,相等於如下的語句
SELECT *
FROM EMP
WHERE (SAL > 1800 AND DEPTNO = 20) OR (DEPTNO = 30);

– 正確的語句如下
SELECT *
FROM EMP
WHERE (SAL > 1800) AND (DEPTNO = 20 OR DEPTNO = 30);


– 9.使用IN作為查詢條件,IN表示包含的意思,也可以使用OR來完成

– 查詢職位是"MANAGER" 或 "ANALYST"的員工資訊
SELECT *
FROM EMP
WHERE JOB IN (“MANAGER”,“ANALYST”);

– IN 也可以使用OR來完成
SELECT *
FROM EMP
WHERE JOB = “MANAGER” OR JOB = “ANALYST”;

– 查詢薪水是1600 或 3000的員工資訊
SELECT *
FROM EMP
WHERE SAL IN (1600,3000);

SELECT *
FROM EMP
WHERE SAL =1600 OR SAL = 3000;

– 查詢薪水不是(1600,3000)的員工
SELECT *
FROM EMP
WHERE SAL NOT IN (1600,3000);

– 另一種方式:薪水既不是1600,並且薪水也不是3000
SELECT *
FROM EMP
WHERE SAL <> 1600 AND SAL <> 3000;


– 10.使用not作為查詢條件,NOT是取反的意思

– 查詢出薪水不是1600和薪水不是3000的員工
– 方式1:
SELECT *
FROM EMP
WHERE SAL NOT IN (1600,3000);

– 方式2:
SELECT *
FROM EMP
WHERE SAL <> 1600 AND SAL <> 3000;

– 方式3:
SELECT *
FROM EMP
WHERE NOT(SAL =1600 OR SAL =3000);

– 查詢津貼不是NULL的員工
SELECT *
FROM EMP
WHERE COMM IS NOT NULL;


– 11.使用LIKE執行模糊查詢
– 什麼是模糊查詢?模糊是專門用字元型資料作為查詢條件的,但是字元型的查詢條件又不是明確的
– 和LIKE 配套的兩個萬用字元
– % :表示0個或多個任意的字元
– _ :表示一個任意的字元

– 查詢名字中有"A"的員工
SELECT *
FROM EMP
WHERE ENAME LIKE “%A%”;

– 查詢名字以A開頭的員工
SELECT *
FROM EMP
WHERE ENAME LIKE “A%”;

– 查詢名字的第二個字元是A的員工
SELECT *
FROM EMP
WHERE ENAME LIKE “_A%”;

– 查詢名字的倒數第三個字元是A的員工
SELECT *
FROM EMP
WHERE ENAME LIKE “%A__”;


– 更新語句
UPDATE EMP SET ENAME = “SMI%TH” WHERE EMPNO =7369;
UPDATE EMP SET ENAME = “SMI_TH” WHERE EMPNO =7369;

– 恢復資料
UPDATE EMP SET ENAME = “SMITH” WHERE EMPNO =7369;

– 查詢名字中有% 或 _ 的員工,必須要使用轉義符,也就是要查詢\後面的字元
SELECT *
FROM EMP
WHERE ENAME LIKE “%%%”;

SELECT *
FROM EMP
WHERE ENAME LIKE “%_%”;

/豪華的分割線*********/
– 對查詢結果進行排序,需要使用ORDER BY子句
/*
語法
SELECT 自動列表
FROM 表名
[WHERE 查詢條件]
[ORDER BY 排序欄位1,排序欄位2,…]

語句執行的順序
1.SELECT FROM 查詢出全部的資料
2.使用WHERE對資料進行過濾
3.過濾後的資料使用ORDER BY進行排序
*/

– 排序的時候,可以按照單個欄位排序,也可以按照多個欄位排序

– =============================================================================================================
– 1.排序的時候,可以按照單個欄位排序

SELECT *
FROM EMP
WHERE DEPTNO = 20;

– 查詢出來的結果預設是沒有順序的,我們如果需要對查詢結果排序,就需要使用ORDER BY 子句對結果進行排序
SELECT *
FROM EMP
WHERE DEPTNO = 20
ORDER BY SAL;

– 按照欄位排序的時候,預設的是按照欄位升序排列,我們可以指定欄位的排序順序
SELECT *
FROM EMP
WHERE DEPTNO = 20
ORDER BY SAL ASC; – 指定按照sal升序排列

SELECT *
FROM EMP
WHERE DEPTNO = 20
ORDER BY SAL DESC; – 指定按照sal降序排列

– =============================================================================================================
– 2.排序的時候,可以按照多個欄位排序,每個欄位可以使用不同的排序規則

– 查詢工資大於1600的員工資訊,並且按照部門編號升序排列,工資降序排序
SELECT *
FROM EMP
WHERE SAL > 1600
ORDER BY DEPTNO ASC ,SAL DESC;

– =============================================================================================================
– 3.排序的時候,可以使用欄位別名對結果進行排序

– 查詢員工的年薪資訊,並且按照年薪降序排列
SELECT EMPNO ,ENAME ,SAL ,SAL *12 “年薪”
FROM EMP
ORDER BY 年薪 DESC;

– =============================================================================================================
– 4.按照欄位在查詢列表中的位置進行排序,
– 在下面的查詢結果中,SAL欄位的位置是6.排序的時候 ORDER BY 6,也就是按照SAL進行排序
– 但是這種方式不要使用;因為表中的欄位會隨時發生變化
SELECT *
FROM EMP
ORDER BY 6;

/豪華的分割線*********/
– 資料庫函式,類似於Java的方法,可以接收一個或多個引數,在函式內部完成計算,並且最終返回結算結果

– 資料庫函式的分類(Java中沒有這種方式)
– 1.單行函式:每次將單條的資料當做引數,輸入給函式,得到這行資料對應的結果
– 2.多行函式:每次將多條的記錄當做引數,輸入給函式,得到多行記錄對應的單行結果
– 例如:查詢所有員工的最高工資,我們需要把14個SAL都輸入給函式,最終得到一條結果

– 注意:
– 1.使用函式的時候我們是把查詢結果當做引數輸入給函式的,函式的執行結果並不會影響表中原來的資料
– 2.資料庫函式是有方言的;也就是有可能在A資料庫中可以執行的函式,在B資料庫中無法執行

– 單行函式

– =============================================================================================================
– 1.LOWER()函式,將字元型的資料轉換為小寫的字元
– 使用方式: LOWER(字元型的的欄位或字元型的資料)

SELECT EMPNO ,ENAME “原來的名字” ,LOWER(ENAME) “小寫的名字”
FROM EMP;

– 我們在資料庫嚴格區分大小寫的情況下,讓資料庫忽略大小寫
SELECT *
FROM EMP
WHERE BINARY LOWER(ENAME) = ‘smith’; – 把ENAME轉換為小寫的字元之後,再去和"smith"進行比較

– =============================================================================================================
– 2.UPPER()函式,將字元型的資料轉換為大寫的字元
– 使用方式: UPPER(字元型的的欄位或字元型的資料)

– 我們在資料庫嚴格區分大小寫的情況下,讓資料庫忽略大小寫
SELECT *
FROM EMP
WHERE BINARY ENAME = UPPER(‘smith’); – 把小寫的"smith"轉換為大寫的,也就是"SMITH",然後再去和EANME進行比較

– =============================================================================================================
– 3.SUBSTR()擷取字串
– 使用方式:SUBSTR(被擷取欄位名稱,起啟下標,擷取長度) – 下標從1開始

– 擷取員工的名字,從第二個字元開始擷取,擷取一個長度
SELECT EMPNO ,ENAME “原來的名字” ,SUBSTR(ENAME,2,1) “擷取的名字”
FROM EMP ;

– 查詢名字的第二個字元是A的員工
SELECT EMPNO ,ENAME “原來的名字” ,SUBSTR(ENAME,2,1) “擷取的名字”
FROM EMP
WHERE SUBSTR(ENAME,2,1) = “A”;

– 也可以使用模糊查詢完成上面的功能
SELECT *
FROM EMP
WHERE ENAME LIKE “_A%”;

– =============================================================================================================
– 4.LENGTH()函式,返回字元型資料的長度,也就是字元的個數
– 使用方式: LENGTH (字元型的欄位或字元型的資料)

– 查詢員工的名字及其名字的長度
SELECT EMPNO,ENAME ,LENGTH(ENAME) “名字的長度”
FROM EMP;

– =============================================================================================================
– 5.TRIM() 去除字元型資料首尾的空格,但是不會去除中間的空格
– MySql中也是採用Unicode編碼的," "空格也是一個有效的字元

– 更新資料
UPDATE EMP SET ENAME = " SMI TH " WHERE EMPNO =7369;

– 單行函式是可以巢狀的! 巢狀的時候首先執行裡面的函式,把裡面函式的結果當做外面函式的引數
SELECT EMPNO ,ENAME “原來的名字” ,LENGTH(ENAME) “原來名字的長度” , TRIM(ENAME) “去除首尾空格之後的名字” ,LENGTH( TRIM(ENAME) ) “去除首尾空格之後名字的長度”
FROM EMP
WHERE EMPNO =7369 ;

– =============================================================================================================
– 6.ROUND函式:四捨五入函式,對數值的資料進行四捨五入
– 用法:ROUND(要四捨五入的數字,四捨五入到哪一位),預設保留整數位

– 查詢EMP表的結構,SAL和COMM欄位的型別是double(7,2) ,表示帶小數的數值,資料的有效位數是7位,小數點後佔2位
– 測試double(7,2)這種型別
UPDATE EMP SET ENAME=“SMITH”, SAL = 753.368 WHERE EMPNO =7369;
SELECT * FROM EMP;

– 恢復資料
UPDATE EMP SET ENAME=“SMITH”, SAL = 800 WHERE EMPNO =7369;

– 查詢7369的工資,精確到不同的位數
SELECT EMPNO,ENAME ,SAL “原來的工資” ,ROUND(SAL) “精確到個位的工資” ,ROUND(SAL,0) “精確到個位的工資”,ROUND(SAL,1) “精確到小數點後1位的工資”
,ROUND(SAL,-1) “精確到小數點後-1位(也就是十位)的工資”
FROM EMP
WHERE EMPNO =7369;

– 把175.3654這個常數精確到不同的位數
– 下面的查詢語句中沒有FROM,實際上這是從資料庫的系統表中進行相關的查詢,表名可以忽略
– 可以使用這種方式處理常數
SELECT 175.3654 “原來的數值” ,ROUND(175.3654 ,0) “精確到個位的數值” ,ROUND(175.3654 ,1) “精確到小數點後1位的數值” ,
ROUND(175.3654 ,-1) “精確到十位的數值” ;

– =============================================================================================================
– 7.RAND() 產生隨機小數(0~0.9999999)的函式

– 產生1~100的隨機整數
SELECT ROUND(RAND()*99 +1 ) ; – 0~0.99999 *99 -> 0~98.9999 +1-> 1~99.999 -> 四捨五入 -> 1~100

– =============================================================================================================
– 8.IFNULL()函式,專門用來處理NULL資料的

– NULL是資料庫中一種特殊的資料,三種主要型別都支援NULL
– 注意:在算術表示式中如果出現NULL,則結果肯定是NULL

– 出現員工的年收入 (年收入 = (SAL + COMM) * 12)
SELECT EMPNO,ENAME ,SAL ,COMM ,(SAL+COMM) * 12 “年收入”
FROM EMP ;

– 正確的處理方式:如果COMM是NULL,就把COMM替換成0,這就是IFNULL()的使用方式
SELECT EMPNO,ENAME ,SAL ,COMM ,(SAL+ IFNULL(COMM,0)) * 12 “年收入”
FROM EMP ;

– 查詢員工的年收入,如果COMM是NULL,就替換為100
SELECT EMPNO,ENAME ,SAL ,COMM ,(SAL+ IFNULL(COMM,100)) * 12 “年收入”
FROM EMP ;

– =============================================================================================================
– 9.CASE WHEN 函式,執行分支語句的功能

– 用法:匹配工作崗位,當為MANAGER時,薪水上調10%,當為SALESMAN時,薪水上調50%,其它崗位薪水不變
– 如果職位是"MANAGER",則返回SAL1.1; 如果職位是"SALESMAN",則返回SAL1.5; 否則直接返回SAL;
SELECT EMPNO,ENAME,JOB ,SAL ,(CASE JOB WHEN “MANAGER” THEN SAL1.1 WHEN “SALESMAN” THEN SAL1.5 ELSE SAL END) “NEWSAL”
FROM EMP;

SELECT * FROM EMP;

– =============================================================================================================
– 10.STR_TO_DATE(str,format) 函式,把字元型的資料轉換為日期型的資料

– 查詢僱傭日期是"1981-02-22"的員工的資訊
SELECT *
FROM EMP
WHERE HIREDATE = “1981-02-22”;

– 查詢條件中使用的 HIREDATE = “1981-02-22”, 實際上"1981-02-22"是一個字元型的資料,而HIREDATE欄位的型別是DATE型別
– 字元型的資料和日期型的資料進行有效的比較,說明資料庫中自動的字元型的資料轉換為日期型的資料
– 使用的就是STR_TO_DATE()函式進行轉換的.

– 上面語句的實際執行過程如下
SELECT *
FROM EMP
WHERE HIREDATE = STR_TO_DATE(“1981-02-22”,"%Y-%m-%d");

– 注意:使用STR_TO_DATE()函式的時候,日期字串的格式必須要和模板的格式一致,轉換才能成功
SELECT *
FROM EMP
WHERE HIREDATE = STR_TO_DATE(“1981/22/02”,"%Y/%d/%m");

– 關於日期型的資料,後面我們會繼續講解

– =============================================================================================================
– 11.DATE_FORMAT(date,format) 將日期型的資料轉為為特定格式的字串

– 查詢員工表的資訊
SELECT * FROM EMP;

– 在上面的查詢結果中,HIREDATE 欄位顯示的資料是"1980-12-17"等,實際上這是一個字元型的資料
– MySql會自動的把日期型的資料轉換為字元型的資料,預設的格式就是"年-月-日"
– 上面語句的實際執行過程如下
SELECT EMPNO,ENAME,HIREDATE ,DATE_FORMAT(HIREDATE,"%Y-%m-%d")
FROM EMP;

– 我們可以使用DATE_FORMAT()把字元型的資料轉換為特定格式的字串
SELECT EMPNO,ENAME,HIREDATE ,DATE_FORMAT(HIREDATE,"%Y-%m-%d") HIREDATE1, DATE_FORMAT(HIREDATE,"%Y/%m/%d") HIREDATE2
,DATE_FORMAT(HIREDATE,"%Y-%m/%d") HIREDATE3
FROM EMP;

– 關於日期型的資料,後面我們會繼續講解

/豪華的分割線*********/
– =============================================================================================================
– =============================================================================================================
– =============================================================================================================
– =============================================================================================================


1.drop database bjpowernode刪除資料庫
2.查詢EMP表的建表語句show create table emp
3.選擇我們正在執行的資料庫
select database();
4.查詢表的結構
desc emp;
5.再次查詢資料庫中的表
show tables
show databases
create database bjpowernode
use bjpowernode
在資料庫中,通過一個個的表來儲存資訊,表中行也有列,列也稱作為欄位

倆種登陸方式,遠端登陸:mysql -uroot -proot -h192.168.148.8 P3306

	本地登陸:mysql -uroot -proot

在cmd中輸入net start mysql
或者net stop mysql判斷mysql命令是否能用

將字元型的資料轉化為特定格式的字串 :date_format(HIREDATE,"%Y-%M-%D");

where hiredate = str _ to_date(“1981/02/03”,"%y/%m/%d");

ifnull(comm,100);

/豪華的分割線*********/
– 資料庫函式

– 多行函式:每次將多條記錄當做引數,輸入給函式,得到多行記錄對應的單行結果
– 多行函式也稱為組函式,分組函式,聚合函式

– 多行函式的注意事項:
– 1.多行函式會自動的忽略NULL,不需要手動的用WHERE排除NULL
– 2.多行函式不能出現在WHERE子句中

SELECT * FROM EMP;

– =============================================================================================================
– 1.計算數值型資料總和的SUM()函式,只能針對數值型的資料

– 出現員工的工資總和,也就是把14個SAL累計在一起
SELECT SUM(SAL) SUMSAL FROM EMP;

– 出現員工的津貼總和;把4個不為NULL的comm進行累計的,因為組函式會自動的忽略空值
SELECT SUM(COMM) SUMCOMM FROM EMP;

– 查詢員工的月收入總和 (月收入 = SAL + COMM)
– 下面的語句是錯誤的!因為:這是把4個sum+comm 不為null的資料進行累計的
SELECT SUM(SAL + COMM) SUMSAL FROM EMP;

– 正確的語句:需要使用IFNULL對COMM進行處理,
SELECT SUM(SAL + IFNULL(COMM,0)) SUMSAL1 ,(SUM(SAL) + SUM(COMM))SUMSAL2 FROM EMP;

– =============================================================================================================
– 2.查詢記錄總和的count()函式

– count()函式有兩種用法
– (1)count(*) 查詢表中所有記錄總數
– (2)count(欄位) 查詢表中指定欄位不為null的記錄總數

– 查詢EMP表的記錄總數
SELECT COUNT(*) TOTALNUM FROM EMP;

– 查詢comm不為null的記錄總數
SELECT * FROM EMP WHERE COMM IS NOT NULL;
SELECT COUNT(COMM) FROM EMP;

– =============================================================================================================
– 3.查詢平均值的AVG()函式,只能針對數值型的資料

– 查詢所有員工的平均工資
SELECT AVG(SAL) AVGSAL1 , SUM(SAL)/COUNT(*) AVGSAL2 FROM EMP;

– 查詢員工的平均津貼
SELECT AVG(COMM) AVGCOMM1 , SUM(COMM)/COUNT(COMM) AVGCOMM1 FROM EMP;

– =============================================================================================================
– 4.查詢最大值得MAX()函式,可以適用於三種主要的型別

– 更新資料
UPDATE EMP SET SAL = 5000 WHERE EMPNO =7369;

SELECT * FROM EMP ORDER BY SAL DESC;

– 查詢員工的最大工資
SELECT MAX(SAL) MAXSAL FROM EMP;

– 查詢最大的名字;字元型資料也是有大小的.MySql中字元型資料的大小和Java中字元大小的規則是一樣的!
– MySql和Java中字元的大小是由其Unicode編碼來決定的,例如:a的編碼是97,b的編碼是98,所以a 小於 b
SELECT MAX(ENAME) MAXENAME FROM EMP;

– 查詢最大的僱傭日期,也就是最晚的入職日期
– 日期型的資料也是有大小的,日期型別資料的大小可以由其字面值來決定,例如"1987"小於"2018"
SELECT MAX(HIREDATE) MAXHIREDATE FROM EMP;

– =============================================================================================================
– 5.查詢最小中的MIN()函式,適用於三種主要型別

– 更新資料
UPDATE EMP SET SAL = 800 WHERE EMPNO =7369;

– 查詢最小的工資
SELECT MIN(SAL) MINSAL FROM EMP;

– 查詢最小的名字
SELECT MIN(ENAME) MINENAME FROM EMP;

– 查詢最小的僱傭日期,也就是最早的僱傭日期
SELECT MIN(HIREDATE) MINHIREDATE FROM EMP;

– =============================================================================================================
– 6.多個多行函式可以在一起使用;
SELECT MAX(SAL) MAXSAL ,MIN(SAL) MINSAL ,AVG(SAL) AVGSAL ,SUM(SAL)SUMSAL ,SUM(COMM) SUMCOMM
FROM EMP

– 多行函式不能巢狀
SELECT MAX(AVG(SAL)) FROM EMP;

– =============================================================================================================
– 7.多行函式不能出現在WHERE子句中

– 查詢工資大於平均工資的員工資訊
SELECT *
FROM EMP
WHERE SAL > AVG(SAL);

/豪華的分割線*********/
– 使用 DISTINCT 去除查詢結果中重複的記錄
– (1)DISTINCT只能出現在SELECT之後,查詢列表之前
– (2)DISTINCT可以去除單列重複的資料,也可以去除多列重複的資料

– =============================================================================================================
– 1.DISTINCT可以去除單列重複的資料

– 查詢所有員工所從事的職位
SELECT DISTINCT JOB FROM EMP;

– 上面的查詢結果中有大量的重複資料,這時候我們就需要使用DISTINCT可以去除單列重複的資料
SELECT JOB FROM EMP;

– =============================================================================================================
– 2.DISTINCT可以去除多列重複的資料

– 查詢員工的職位資訊和部門編號資訊
SELECT DEPTNO ,JOB FROM EMP;

– 上面的查詢結果中,deptno + job ,兩列資料的組合有重複的資料,需要使用DISTINCT去除重複的資料
SELECT DISTINCT DEPTNO ,JOB FROM EMP ORDER BY DEPTNO;

/豪華的分割線*********/
– 分組查詢,也就是把總的資料按照不同的條件劃分為多組,然後使用組函式進行查詢,把資料分成多少組,就會得到多少條結果
– 例如:把所有的員工按照部門編號分組,將分成三組,然後查詢每組的最高工資,將得到三個結果
SELECT * FROM EMP ORDER BY DEPTNO;

– 分組查詢需要使用GROUP BY子句(從句)
/*
分組查詢的語法
SELECT 查詢列表
FROM 表名
GROUP BY 分組欄位1 [,分組欄位2]

分組查詢的規則:
(1)查詢在查詢列表中的欄位,要麼出現在組函式中,要麼出現在GROUP BY子句中.這是分組查詢的首先方式
(2)分組欄位只出現在GROUP BY子句中;這種方式的查詢結果不明確,所以儘量不要使用這種方式
*/

– =============================================================================================================
– 1,按照單個欄位進行分組

– 按照部門編號分組,查詢最大工資
– 分析:出現在查詢列表中有兩個欄位,是DEPTNO和SAL; SAL出現在組函式中,DEPTNO出現在GROUP BY子句中,所以下面語句是符合規則的
SELECT DEPTNO ,MAX(SAL) MAXSAL MAXSAL
FROM EMP
GROUP BY DEPTNO ;

– 校驗資料
SELECT *
FROM EMP
ORDER BY DEPTNO ,SAL DESC;

– 分析,分組欄位DEPTNO只出現在GROUP BY子句中,這個語句也是符合規則的
– 但是這種方式的查詢結果不明確,所以儘量不要使用這種方式
SELECT MAX(SAL) MAXSAL
FROM EMP
GROUP BY DEPTNO;

– 按照職位分組,查詢員工的平均工資
SELECT JOB ,AVG(SAL) AVGSAL
FROM EMP
GROUP BY JOB;

– 按照部門編號分組,查詢最大工資及其最大工資的員工姓名
– 分析,出現在查詢列表中有三個欄位(ENAME,SAL,DEPTNO);SAL出現在組函式中,DEPTNO出現在GROUP BY子句中
– 但是,ENAME既沒有出現在組函式中,也沒有出現在GROUP BY子句中,所以不符合規則的!
– 這樣的語句在Oracle中根本無法執行;在MySql中可以執行,但是查詢結果是錯誤的!
SELECT ENAME, DEPTNO,MAX(SAL) MAXSAL
FROM EMP
GROUP BY DEPTNO;

– 分析,出現在查詢列表中的欄位有三個(DEPTNO ,SAL,COMM) ,SAL和COMM出現在組函式中,DEPTNO出現在GROUP BY子句中
– 符合規則的
SELECT DEPTNO, MAX(SAL) MAXSAL ,MIN(SAL) MINSAL ,AVG(SAL) AVGSAL ,SUM(SAL)SUMSAL ,SUM(COMM) SUMCOMM
FROM EMP
GROUP BY DEPTNO;

– =============================================================================================================
– 2.按照多個欄位進行分組

– 按照部門編號和職位分組,查詢最高工資
– 分析:出現在查詢列表中有三個欄位(DEPTNO,JOB ,SAL) ;SAL出現在分組函式中,DEPTNO和JOB出現在GROUP BY子句中,這個語句符合規則
SELECT DEPTNO,JOB ,MAX(SAL) MAXSAL
FROM EMP
GROUP BY DEPTNO ,JOB;

– =============================================================================================================
– 3.對分組後的資料進行過濾

– 按照部門編號分組,查詢平均工資,並且顯示平均工資大於2000的資料
– 按照我們以前講的內容,要對查詢結果進行過濾,需要使用WHERE子句
– 但是下面的語句是錯誤的,因為多行函式不能出現在WHERE子句中
SELECT DEPTNO ,AVG(SAL) AVGSAL
FROM EMP
GROUP BY DEPTNO
WHERE AVGSAL > 2000;

– 如果我們需要對分組後的資料進行過濾,是不能使用WHERE子句的,而是要使用HAVING子句
– HAVING子句就是專門對分組之後的資料進行過濾的
SELECT DEPTNO ,AVG(SAL) AVGSAL
FROM EMP
GROUP BY DEPTNO
HAVING AVGSAL > 2000;

SELECT DEPTNO ,AVG(SAL) AVGSAL
FROM EMP
GROUP BY DEPTNO
HAVING AVG(SAL) > 2000;

/豪華的分割線*********/
– 簡單出現語句的完整語句
/*
SELECT 欄位列表
FROM 表名
[WHERE 查詢條件]
[GROUP BY 分組欄位]
[HAVING 查詢條件]
[ORDER BY 排序欄位]

以上語句執行的順序
1.SELECT FROM 查詢出全部的資料
2.使用WEHRE對查詢結果進行過濾
3.過濾後的資料使用GROUP BY進行分組
4.分組後的資料使用HAVING再次過濾
5.再次過濾後的資料使用ORDER BY進行排序

注意:
1.以上語句的順序是固定的
2.需要對資料進行過濾,優先使用WHERE進行過濾,這樣的效率比較高
*/

– 把COMM為NULL的員工按照部門編號分組,查詢平均工資,並且顯示平均工資大於2000的資料,然後按照平均工資升序排序
SELECT DEPTNO, ROUND(AVG(SAL)) AVGSAL
FROM EMP
WHERE COMM IS NULL
GROUP BY DEPTNO
HAVING AVGSAL > 2000
ORDER BY AVGSAL ASC;

/豪華的分割線*********/
– 多表查詢,也稱為跨表查詢,也稱為聯合查詢,也就是從多個表中查詢相關的資料

– 多表查詢的分類
– 1按照語法的年代劃分:
– (1).SQL1992標準:FROM後面是多個表,多個表通過逗號分隔
– (2).SQL1999標準:FROM 後面是一個表,通過JOIN方式連線其他的表

– 2.按照連線的方式分:
– (1)內連線(INNER JOIN):可以查詢滿足一一對應關係的資料;例如這個員工有所屬的部門,這個部門有對應的員工,這樣的資料滿足
– 一一對應的關係,可以使用內連線查詢出來;換一個角度,也就是查詢兩個表中有重複資料的記錄
– (2)外連線(OUTER JOIN):可以查詢不滿足一一對應關係的資料;例如有的員工沒有部門,有的部門沒有員工,這樣的資料不滿足一一
– 對應的關係,使用內連線是查詢不到的,但是可以使用外連線查詢出來;例如7369這個員工沒有對供應的部門,40這個部門沒有對應
– 的員工,這樣的資料用內連線是查詢不到的,但是可以使用外連線查詢出來

– 3.內連線的分類
– (1)等值連線
– (2)非等值連線
– (3)自連線

– 4.外連線的分類
– (1)左外連線(LEFT OUTER JOIN)
– (2)右外連線(RIGHT OUTER JOIN)
– (3)全外連線(FULL OUTER JOIN)

– =============================================================================================================
– 內連線的分類
– (1)等值連線:建立在父子表關係上,用等號來連線兩個表
– (2)非等值連線:兩個表之間沒有父子關係,用非等號來連線兩個表
– (3)自連線:通過別名將一個表虛擬成兩個表(父子表),然後再這兩個表上面做等值連線


– (1)等值連線:建立在父子表關係上,用等號來連線兩個表

– 查詢員工資訊及其部門資訊
SELECT * FROM EMP;
SELECT * FROM DEPT;


– SQL1992標準

– 當兩個表中有相同名稱的欄位的時候,為了區分不同表中的欄位,需要使用表名作為字首
SELECT EMP.EMPNO,EMP.ENAME,EMP.JOB ,EMP.MGR ,EMP.HIREDATE ,EMP.SAL,EMP.COMM ,EMP.DEPTNO,DEPT.DEPTNO ,DEPT.DNAME,DEPT.LOC
FROM EMP ,DEPT;

– 上面的查詢結果中有56條件記錄;EMP表中有14條記錄,DEPT表中有4條記錄 14*4 = 56;
– 這樣的結果是錯誤的!這種現象稱為笛卡爾乘積.
– 笛卡爾乘積產生的原因:就是因為在連線查詢的時候沒有加入正確的連線條件
– 如何避免笛卡爾乘積呢?需要加入正確的連線條件
SELECT EMP.EMPNO,EMP.ENAME,EMP.JOB ,EMP.MGR ,EMP.HIREDATE ,EMP.SAL,EMP.COMM ,DEPT.DEPTNO ,DEPT.DNAME,DEPT.LOC
FROM EMP ,DEPT
WHERE EMP.DEPTNO = DEPT.DEPTNO;

– 使用表名作為字首的時候,如果表名很長,寫起來也忒麻煩了,可以被表起個簡單的別名
SELECT E.EMPNO,E.ENAME,E.JOB,E.HIREDATE,E.SAL,E.COMM,D.DEPTNO,D.DNAME,D.LOC
FROM EMP E ,DEPT D
WHERE E.DEPTNO = D.DEPTNO;

– 可以在等值連線的基礎上使用AND加入其它的查詢條件
– 查詢部門編號是20的員工資訊及其部門資訊
SELECT E.EMPNO,E.ENAME,E.JOB,E.HIREDATE,E.SAL,E.COMM,D.DEPTNO,D.DNAME,D.LOC
FROM EMP E ,DEPT D
WHERE E.DEPTNO = D.DEPTNO AND D.DEPTNO = 20;

– 查詢工資在1600~3000之間的員工資訊及其部門資訊
SELECT E.EMPNO,E.ENAME,E.JOB ,E.SAL ,E.COMM,D.DEPTNO,D.DNAME,D.LOC
FROM EMP E ,DEPT D
WHERE (E.DEPTNO = D.DEPTNO) AND (E.SAL BETWEEN 1600 AND 3000);


– SQL1999標準:FROM 後面是一個表,通過JOIN方式連線其他的表

– 查詢員工資訊及其部門資訊
SELECT E.EMPNO,E.ENAME,E.JOB ,E.SAL ,E.COMM,D.DEPTNO,D.DNAME,D.LOC
FROM EMP E
INNER JOIN DEPT D ON( E.DEPTNO = D.DEPTNO);

– 在等值連線的基礎上可以使用AND加入其他的查詢條件
SELECT E.EMPNO,E.ENAME,E.JOB ,E.SAL ,E.COMM,D.DEPTNO,D.DNAME,D.LOC
FROM EMP E
INNER JOIN DEPT D ON( E.DEPTNO = D.DEPTNO)
AND D.DEPTNO = 30;

– 在等值連線的基礎上,也可以使用WHERE加入其他的查詢條件
SELECT E.EMPNO,E.ENAME,E.JOB ,E.SAL ,E.COMM, D.DEPTNO,D.DNAME,D.LOC
FROM EMP E
INNER JOIN DEPT D ON( E.DEPTNO = D.DEPTNO)
WHERE D.DEPTNO = 30;

– 使用內連線的時候INNER可以忽略
SELECT E.EMPNO,E.ENAME,E.JOB ,E.SAL ,E.COMM, D.DEPTNO,D.DNAME,D.LOC
FROM EMP E
JOIN DEPT D ON( E.DEPTNO = D.DEPTNO)
WHERE D.DEPTNO = 30;


– (2)非等值連線:兩個表之間沒有父子關係,用非等號來連線兩個表
SELECT * FROM EMP;
SELECT * FROM SALGRADE;

– 查詢員工資訊及其工資級別資訊


– SQL1992標準
SELECT E.* ,S.*
FROM EMP E ,SALGRADE S
WHERE (E.SAL BETWEEN S.LOSAL AND S.HISAL) AND (S.GRADE = 2)


– SQL1999標準
SELECT E.* ,S.*
FROM EMP E
JOIN SALGRADE S ON (E.SAL BETWEEN S.LOSAL AND S.HISAL)
WHERE E.DEPTNO = 20;


– (3)自連線:通過別名將一個表虛擬成兩個表(父子表),然後再這兩個表上面做等值連線
SELECT * FROM EMP;

– 查詢員工資訊及其經理資訊


– SQL1992標準
SELECT E.EMPNO “員工編號”,E.ENAME “員工姓名”,M.EMPNO “經理編號”,M.ENAME “經理姓名”
FROM EMP E ,EMP M
WHERE (E.MGR = M.EMPNO) AND (E.EMPNO = 7369);


– SQL1999標準
SELECT E.EMPNO “員工編號”,E.ENAME “員工姓名”,M.EMPNO “經理編號”,M.ENAME “經理姓名”
FROM EMP E
JOIN EMP M ON (E.MGR = M.EMPNO)
WHERE E.EMPNO =7902;

– =============================================================================================================
– 外連線的分類:外連線(OUTER JOIN):可以查詢不滿足一一對應關係的資料;例如有的員工沒有不買,有的部門沒有員工,這樣的
– 資料不滿足一一對應的關係,使用內連線是查詢不到的,但是可以使用外連線查詢出來;例如7369這個員工沒有對供應的部門,
– 的40這個部門沒有對應員工,這樣的資料用內連線是查詢不到的,但是可以使用外連線查詢出來
– 外連線查詢資料的條數大於等於內連線查詢資料的條數;
– 資料庫會自動把不匹配的資料設定為NULL;

UPDATE EMP SET DEPTNO= NULL WHERE EMPNO =7369;
SELECT * FROM EMP;
SELECT * FROM DEPT;

– 使用內連線之等值連線是無法查詢到7369和40這個部門的資訊的
SELECT E.EMPNO,E.ENAME,E.JOB ,E.SAL ,E.COMM,D.DEPTNO,D.DNAME,D.LOC
FROM EMP E ,DEPT D
WHERE (E.DEPTNO = D.DEPTNO);

– 外連線的分類:
– (1)左外連線(LEFT OUTER JOIN)
– (2)右外連線(RIGHT OUTER JOIN)
– (3)全外連線(FULL OUTER JOIN)


– (1)左外連線(LEFT OUTER JOIN):我們用 LEFT OUTER JOIN 作為分界線,EMP表就是左表,左外連線可以把左表中不滿足對應
– 關係的資料查詢出來;例如7369這個員工沒有對應的部門,可以被查詢出來
SELECT E.EMPNO,E.ENAME ,D.DEPTNO,D.DNAME,D.LOC
FROM EMP E
LEFT OUTER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO);

– 左表的位置是相對的,我們也可以把DEPT表當做左表
SELECT E.EMPNO,E.ENAME ,D.DEPTNO,D.DNAME,D.LOC
FROM DEPT D
LEFT OUTER JOIN EMP E ON (E.DEPTNO = D.DEPTNO);

– 使用外連線的時候,OUTER可以忽略
SELECT E.EMPNO,E.ENAME ,D.DEPTNO,D.DNAME,D.LOC
FROM DEPT D
LEFT JOIN EMP E ON (E.DEPTNO = D.DEPTNO);


– (2)右外連線(RIGHT OUTER JOIN):用RIGHT OUTER JOIN作為分解線,可以把右表中不滿足對應關係的資料查詢出來
– 例如DEPT表 是右表,40這個部門沒有對應的員工,可以被查詢出來
SELECT E.EMPNO,E.ENAME ,D.DEPTNO,D.DNAME,D.LOC
FROM EMP E
RIGHT JOIN DEPT D ON (E.DEPTNO = D.DEPTNO);

– 右表的位置是相對的,我們也可以把EMP表當做右表
SELECT E.EMPNO,E.ENAME ,D.DEPTNO,D.DNAME,D.LOC
FROM DEPT D
RIGHT JOIN EMP E ON (E.DEPTNO = D.DEPTNO);

– 左外連線的功能也可以用右外連線來實現
– 例如我們要查詢dept表中不滿足對應關係的資料,我可以使用左外連線,也可以使用右外連線
SELECT E.EMPNO,E.ENAME ,D.DEPTNO,D.DNAME,D.LOC
FROM EMP E
RIGHT OUTER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO);

SELECT E.EMPNO,E.ENAME ,D.DEPTNO,D.DNAME,D.LOC
FROM DEPT D
LEFT OUTER JOIN EMP E ON (E.DEPTNO = D.DEPTNO);


– (3)全外連線(FULL OUTER JOIN):用FULL OUTER JOIN 作為分界線,可以把左右兩邊表中不滿足對應關係的資料都查詢出來
– Oracle支援全外連線;但是MySql不支援全外連線
SELECT E.EMPNO,E.ENAME ,D.DEPTNO,D.DNAME,D.LOC
FROM DEPT D
FULL OUTER JOIN EMP E ON (E.DEPTNO = D.DEPTNO);

– =============================================================================================================
– 從N個表中查詢相關的資料,需要N-1個INNER JOIN 句(這就是多表查詢的原理)

– 查詢員工資訊及其部門資訊及其工資級別資訊

– SQL1992標準
SELECT E.EMPNO,E.ENAME,E.JOB,E.MGR,E.HIREDATE,E.SAL ,E.COMM,D.DEPTNO,D.DNAME,D.LOC,S.GRADE,S.LOSAL,S.HISAL
FROM EMP E ,DEPT D,SALGRADE S
WHERE E.SAL BETWEEN S.LOSAL AND S.HISAL AND E.DEPTNO = D.DEPTNO AND D.DEPTNO = 20;

– SQL1999標準
SELECT E.EMPNO,E.ENAME,E.JOB,E.MGR,E.HIREDATE,E.SAL ,E.COMM,D.DEPTNO,D.DNAME,D.LOC,S.GRADE,S.LOSAL,S.HISAL
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
INNER JOIN SALGRADE S ON (E.SAL BETWEEN S.LOSAL AND S.HISAL)
WHERE D.DEPTNO = 20;

/豪華的分割線*********/
– 子查詢:用來給主查詢提供查詢條件而首先執行的一個查詢,然後主查詢使用子查詢的查詢結果
– 為了語法的清晰,要把子查詢放到()裡面

– 子查詢的分類
– 1.出現在WHERE後面的子查詢,用來給主查詢提供查詢條件的
– 2.出現在FROM後面的子查詢,用來給主查詢提供查詢資料的
– 3.出現在查詢列表中的子查詢,功能類似於外連線的效果;這種方式知道就可以了

– =============================================================================================================
– 1.出現在WHERE後面的子查詢,用來給主查詢提供查詢條件的

– 查詢工資比平均工資大的員工的資訊
– 思路:
– (1)查詢員工表的平均工資
SELECT AVG(SAL) FROM EMP;

– (2) 把上面的查詢結果當做條件
SELECT *
FROM EMP
WHERE SAL > 2073;

– (3)把上面的兩個查詢語句合併到一起
SELECT *
FROM EMP
WHERE SAL > ( SELECT AVG(SAL) FROM EMP );

– =============================================================================================================
– 2.出現在FROM後面的子查詢,用來給主查詢提供查詢資料的
– 語句執行的過程:把子查詢的查詢結果當做一個臨時表T,然後主查詢從這個臨時表中查詢相關的資料

SELECT T.*
FROM ( SELECT E.EMPNO,E.ENAME,E.JOB,E.MGR,E.HIREDATE,E.SAL ,E.COMM,D.DEPTNO,D.DNAME,D.LOC,S.GRADE,S.LOSAL,S.HISAL
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
INNER JOIN SALGRADE S ON (E.SAL BETWEEN S.LOSAL AND S.HISAL)) T
WHERE T.EMPNO = 7499;

– =============================================================================================================
– 3.出現在查詢列表中的子查詢,功能類似於外連線的效果;這種方式知道就可以了;
SELECT E.EMPNO,E.ENAME ,E.SAL ,E.DEPTNO ,(SELECT D.DNAME FROM DEPT D WHERE E.DEPTNO = D.DEPTNO)
FROM EMP E ;

/豪華的分割線*********/
– 分組查詢,多表查詢,子查詢綜合應用


– 案例1:按照部門編號分組查詢最大工資,及其最大工資的員工姓名
– 思路:
– (1)按照部門編號分組查詢最高工資
SELECT DEPTNO ,MAX(SAL) MAXSAL
FROM EMP
GROUP BY DEPTNO;

– (2)把上面的查詢結果當做一個臨時表T,和EMP表進行連線查詢,兩個表的連線條件是(E.DEPTNO = T.DEPTNO AND E.SAL = T.MAXSAL)
SELECT E.EMPNO,E.ENAME,T.MAXSAL ,T.DEPTNO
FROM EMP E
INNER JOIN ( SELECT DEPTNO ,MAX(SAL) MAXSAL
FROM EMP
GROUP BY DEPTNO) T ON (E.DEPTNO = T.DEPTNO AND E.SAL = T.MAXSAL)
ORDER BY T.DEPTNO;

– (3)校驗資料
SELECT *
FROM EMP
ORDER BY DEPTNO , SAL DESC;


– 案例2:哪些人的薪水在部門平均薪水之上
– 思路:
– (1)按照部門編號分組查詢平均工資
SELECT DEPTNO ,AVG(SAL) AVGSAL
FROM EMP
GROUP BY DEPTNO;

– (2)把上面的查詢結果當做一個臨時表T,和EMP表進行連線.連線的條件是(E.DEPTNO = T.DEPTNO AND E.SAL > T.AVGSAL)
SELECT E.EMPNO,E.ENAME,E.SAL ,T.AVGSAL ,T.DEPTNO
FROM EMP E
JOIN ( SELECT DEPTNO ,AVG(SAL) AVGSAL
FROM EMP
GROUP BY DEPTNO ) T ON ( T.DEPTNO = E.DEPTNO AND E.SAL > T.AVGSAL )
ORDER BY T.DEPTNO;

/豪華的分割線*********/
– DML語句(資料庫操作語句) ,包括INSERT(向表中插入數) ,DELETE(從表中刪除資料) ,UPDATE(更新表中的資料)
– 我們執行DML語句的時候,資料庫返回的是收到DML語句影響的資料的條數,稱為更新計數器

– =============================================================================================================
– 1.INSERT語句,向表中插入資料
/*
插入語句的語法
INSERT INTO 表名(欄位列表) VALUES (值列表)
欄位列表必須要和值列表一一對應
*/

– 向表中指定的欄位插入資料
– 下面的語句在cmd客戶端中插入失敗!這是因為MySql資料庫的編碼格式是UTF-8,而cmd視窗的編碼格式是GBK
– 但是下面的語句在視窗客戶端中可以執行成功.因為視窗客戶端的編碼格式就是UTF-8
INSERT INTO EMP (EMPNO,ENAME ) VALUES (9000,‘張0’);

– 向表中全部的欄位插入資料
INSERT INTO EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) VALUES (9001,“張1”,“軟體工程師”,7902,‘1982-10-9’,2000,NULL,30);

– 向表中全部欄位插入資料的時候,可以忽略欄位列表
– 也就是說,插入資料的時候如果沒有指明欄位列表,也就是向表中全部欄位插入資料,必須要按照欄位的順序給出足夠的值
INSERT INTO EMP VALUES (9002,“張2”,“軟體工程師”,7902,‘1982-10-9’,2000,NULL,30);

– 下面的語句錯誤,因為沒有指明欄位列表,也即是向表中全部欄位插入資料,但是隻給出了7個值
INSERT INTO EMP VALUES (9003,“張2”,“軟體工程師”,7902,‘1982-10-9’,2000,NULL);


– 關於日期型的資料

INSERT INTO EMP VALUES (9003,“張3”,“軟體工程師”,7902,‘1982-10-9’,2000,NULL,30);

– EMP表的HIREDATE欄位的型別是DATE型別,HIREDATE欄位插入的值是"1982-10-9",而這個值是字元型別的資料
– MySql會自動的呼叫STR_TO_DATE()函式將字元型別的資料轉換為日期型別的資料,上面語句的實際執行過程如下
INSERT INTO EMP VALUES (9003,“張3”,“軟體工程師”,7902, STR_TO_DATE(‘1982-10-9’,"%Y-%m-%d"),2000,NULL,30);

– STR_TO_DATE()這個函式只能在MySql中有效,並且每種資料庫預設的日期格式都是不同的
– MySql預設的日期格式是"年-月-日",而Oracle預設的日期格式是"日-月-年"
– 這樣就造成一個問題,在不同的資料庫中插入日期資料的SQL語句都是不同的,給SQL語句的移植帶來問題
– 所以:在實際的開發中,本來應該是DATE型別的欄位,通常會被設計成字元型的欄位,增加SQL語句的移植性

– 在MySql中提供了一個NOW()函式,可以獲取當前時間點的日期(也就是日期型的資料) ,EMP表的HIREDATE就是date型別的
INSERT INTO EMP VALUES (9004,“張4”,“軟體工程師”,7902,NOW(),2000,NULL,30);

– =============================================================================================================
– 2.使用UPDATE 更新表中的資料
– (1)在更新的時候可以更新單個的欄位,也可以同時更新多個欄位,多個欄位之間使用逗號分隔
– (2)在更新表中的資料的時候,可以用WHERE加入更新條件,這樣會更新滿足條件的資料;如果沒有加入更新條件,則更新所有的資料

UPDATE EMP SET JOB = “高階軟體工程師” ,SAL = 2500 ,COMM=200 WHERE EMPNO IN (9000,9001);

UPDATE EMP SET JOB = “專案經理” ,SAL = 2500 ,COMM=200;

SELECT * FROM EMP;

– =============================================================================================================
– 3,刪除表中的資料,要使用DELETE語句
– (1)刪除表中的資料的時候,可以加入條件,這樣只會刪除滿足條件的資料;如果沒有加入條件則是刪除所有的資料
DELETE FROM EMP WHERE EMPNO >= 9000;

DELETE FROM EMP;

/豪華的分割線*********/
– DDL語句(資料庫定義語句) ,包括CREATE(建立表) ,DROP(刪除表) ,ALTER(修改表)
– 我們執行DDL語句的時候,資料庫返回的是0
– 在資料庫表中是一個個的欄位,欄位所需要的資訊(四個資訊):欄位名稱, 欄位的資料型別, 欄位的長度,欄位的約束
– DDL和DML的區別:DML操作的是表中的資料;DDL操作的是表

– =============================================================================================================
– 建立表的語句
CREATE TABLE STUS(
SID INT(4), – 欄位後面以逗號間隔,
SNAME CHAR(4),
SEX CHAR(1),
BIRTHDAY DATE,
EMAIL VARCHAR(50) – 最後的欄位後面沒有逗號
) /我們可以在這裡指明編碼格式,如果沒有指明編碼格式就是資料庫預設的編碼格式/;

– 說明:
– INT(4)在Oracle中表示4位的整數,返回從0~9999; 不能超過位數限制;
– INT(4)在MySql中表示的是建議長度是4位

DESC STUS;

– 插入測試資料
INSERT INTO STUS VALUES (1,‘張1’,‘男’,‘1992-10-9’,‘[email protected]’);
INSERT INTO STUS VALUES (2,‘張2’,‘男’,‘1992-10-9’,‘[email protected]’);
INSERT INTO STUS VALUES (3,‘張3’,‘男’,‘1992-10-9’,‘[email protected]’);
INSERT INTO STUS VALUES (4,‘張4’,‘男’,‘1992-10-9’,‘[email protected]’);
INSERT INTO STUS VALUES (5,‘張5’,‘M’,‘1992-10-9’,‘[email protected]’);
INSERT INTO STUS VALUES (6,‘張6’,‘女的’,‘1992-10-9’,‘[email protected]’); – 錯誤:SEX欄位的值超過了一個字元的長度限制
INSERT INTO STUS VALUES (10000,‘張6’,‘女’,‘1992-10-9’,‘[email protected]’);

– 查詢結果
SELECT * FROM STUS;


– 刪除表的語句 ;刪除表的時候回連同表中的資料一起刪除掉
DROP TABLE STUS;

– 如果在沒有表的情況下執行刪除表的語句,會導致資料庫儲存,我們可以用如下的語句避免錯誤
– 如果STUS表存在,就刪除;如果不存在,就不刪除了,這樣可以避免錯誤
– 注意:這種語句是MySql特有的,其他的資料庫都不支援這種語句
DROP TABLE IF EXISTS STUS;


– 在建立表的時候,我們可以給欄位提供預設值
DROP TABLE IF EXISTS STUS;
CREATE TABLE STUS(
SID INT(4),
SNAME CHAR(4),
SEX CHAR(1) DEFAULT ‘男’, /給sex欄位提供了預設值:男/
AGE INT(2)
);

– 在插入資料的時候,如果欄位沒有提供相應的資料
– (1)沒有提供預設值欄位會被插入NULL
– (2)有預設值的欄位會被預設的插入預設值
INSERT INTO STUS (SID ,SNAME) VALUES (1,“張1”);

– 當然,提供了預設值的欄位,也可以被插入其他的值
INSERT INTO STUS (SID ,SNAME,SEX) VALUES (2,“張2”,‘女’);

– 查詢資料
SELECT * FROM STUS;


– 我們可以把建表語句和查詢語句結合起來,也就是把查詢語句中的欄位當做新建表的欄位,並且把查詢語句中的結果插入到新表中
DROP TABLE IF EXISTS EMP_BAK;
CREATE TABLE EMP_BAK
AS
SELECT EMPNO,ENAME,JOB,MGR,HIREDATE,SAL ,COMM
FROM EMP
WHERE SAL BETWEEN 1600 AND 3000;

– 從新表中查詢資料
SELECT * FROM EMP_BAK;

– 任何有效的查詢語句都可以和建表語句集合
DROP TABLE IF EXISTS EMP_INFO;

CREATE TABLE EMP_INFO
AS
SELECT E.EMPNO,E.ENAME,E.JOB,E.MGR,E.HIREDATE,E.SAL ,E.COMM,D.DEPTNO,D.DNAME,D.LOC,S.GRADE,S.LOSAL,S.HISAL
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
INNER JOIN SALGRADE S ON (E.SAL BETWEEN S.LOSAL AND S.HISAL);

SELECT * FROM EMP_INFO;


– 如果出現語句中沒有出現結果,則僅僅是把查詢語句中的欄位當做新建表的欄位
CREATE TABLE EMP_BAK
AS
SELECT * FROM EMP WHERE SAL > 21000;

SELECT * FROM EMP_BAK;

– 我們可以把一個插入語句和一個查詢語句結合起來,注意:查詢語句的結果必須要和表的結構一致
– 也就是把查詢語句的結果插入到表中
INSERT INTO EMP_BAK SELECT * FROM EMP WHERE SAL BETWEEN 1600 AND 3000;

– 刪除表
DROP TABLE IF EXISTS EMP_BAK;

– =============================================================================================================
– ALTER,修改表的語句;對錶的修改主要是對欄位的修改,包括ADD(新增欄位),DROP(刪除欄位) ,MODIFY(修改欄位)
– 使用ALTER語句可以讓我們在不影響表中資料的情況下,對錶的結構進行修改

DROP TABLE IF EXISTS STUS;
CREATE TABLE STUS(
SID INT(4),
SNAME CHAR(4),
AGE INT(2),
BIRTHDAY DATE – 注意:DATE型別沒有資料長度
);

– 插入測試資料
INSERT INTO STUS VALUES (1,“張1”,21,‘1992-12-8’);
INSERT INTO STUS VALUES (2,“張2”,21,‘1992-12-8’);
INSERT INTO STUS VALUES (3,“張3”,21,‘1992-12-8’);
INSERT INTO STUS VALUES (4,“張4”,21,‘1992-12-8’);
INSERT INTO STUS VALUES (5,“張5”,21,‘1992-12-8’);

– 查詢資料
SELECT * FROM STUS;


– 使用ALTER語句給表中新增TEL欄位,新的欄位會被新增到表的末尾
ALTER TABLE STUS ADD TEL BIGINT(11);

– 查詢表的結構
DESC STUS;


– 使用ALTER語句修改表中的欄位
– (1)當該欄位中沒有資料的時候,欄位的型別和欄位的長度都是可以隨便修改的
ALTER TABLE STUS MODIFY TEL CHAR(11);
ALTER TABLE STUS MODIFY TEL DATE; – 僅僅是演示語法而已
ALTER TABLE STUS MODIFY AGE INT(3);

– (2)當該欄位中有資料的時候,增大欄位的長度總是可以的
ALTER TABLE STUS MODIFY SNAME CHAR(10);

– (3)當該欄位中有資料的時候,減少欄位的長度,要根據該欄位的最大資料來決定
– 例如:SNAME欄位的最大資料是"張小發動機",其長度是5個字元,所以我們把SNAME從char(10)改為char(5)是可以的
– 但是如果我們想要把SNAME 改成char(4)就會報錯
UPDATE STUS SET SNAME=“張小發動機” WHERE SID=1;
ALTER TABLE STUS MODIFY SNAME CHAR(5);
ALTER TABLE STUS MODIFY SNAME CHAR(4); – 報錯

– (4)當該欄位中有資料的時候,要修改欄位的型別,要看該欄位的資料能否轉換為新的型別
– 如果資料可以轉換為新的型別,則欄位的型別就是可以修改的
– 例如:SID欄位原來的型別是int(4),該欄位的資料是1,2,3,4 ;1,2,3,4這樣的資料可以被轉換為字元型的資料嗎?當然可以了
– 所以我們可以把SID從原來的int(4)改成char(4)
ALTER TABLE STUS MODIFY SID CHAR(4);

– 例如:age欄位的型別是int(3),該欄位的資料是21,22等;21,22這樣的資料能否轉換為DATE型別呢?是不能轉換的
– 所以:age欄位是不能從int(3)改成Date型別的
ALTER TABLE STUS MODIFY AGE DATE;

– 查詢資料
SELECT