MySQL資料庫(良心資料)
一、MySQL資料庫
1、資料庫簡介
1.1、資料庫的概念
資料庫就是用來儲存和管理資料的倉庫。資料庫儲存資料的優點:
l 可儲存大量資料;
l 方便檢索;
l 保持資料的一致性、完整性;
l 安全,可共享;
l 通過組合分析,可產生新資料;
1.2、資料庫的發展歷程
l 沒有資料庫,使用磁碟檔案儲存資料;
l 層次結構模型資料庫;
l 網狀結構模型資料;
l 關係結構模型資料庫:使用二維表格來儲存資料;
l 關係-物件模型資料庫;
MySQL就是關係型資料庫。
1.3、常見資料庫
l Oracle:甲骨文;
l MySQL:甲骨文;
l DB2:IBM;
l SQL Server:微軟;
l Sybase:賽爾斯;
1.4、理解資料庫
我們所說的資料庫泛指“關係型資料庫管理系統(RDBMS-Relational database management system)”,即“資料庫伺服器”。
當我們安裝了資料庫伺服器後,就可以在資料庫伺服器中建立資料庫,每個資料庫中還可以包含多張表。
資料庫表就是一個多行多列的表格。在建立表時,需要指定表的列數,以及列名稱,列型別等資訊。而不用指定表格的行數,行數是沒有上限的。下面是tab_student表的結構:
當把表格建立好了之後,就可以向表中新增資料了。向表格新增資料是以行為單位的!下面是s_student表的記錄:
s_id |
s_name |
s_age |
s_sex |
s_1001 |
tom |
23 |
m |
s_1002 |
liyi |
32 |
w |
1_1003 |
jack |
44 |
m |
資料庫的理解:
l RDBMS=管理員(manager)+倉庫(database)
l database=N個table
l table:
l 表結構:定義表的列名和列型別
l 表記錄:一行一行的記錄
1.5、應用程式與資料庫
應用程式使用資料庫完成對資料的儲存。
2、安裝MySQL資料庫
2.1、安裝MySQL
參考:MySQL安裝圖解.doc
2.2、MySQL目錄結構
1、MySQL安裝成功後會在兩個目錄中儲存檔案:
- C:\ProgramData\MySQL\MySQL Server 5.5\data:DBMS資料庫檔案(解除安裝MySQL時不會刪除這個目錄,需要自己手動刪除);
- D:\Program Files\MySQL\MySQL Server 5.5:DBMS管理程式
2、MySQL重要檔案
- D:\Program Files\MySQL\MySQL Server 5.5\bin\mysql.exe:客戶端程式,用來操作伺服器。但必須保證伺服器已開啟才能連線上;
- D:\Program Files\MySQL\MySQL Server 5.5\bin\mysqld.exe:伺服器程式,必須先啟動它,客戶端才能連線上伺服器;
- D:\Program Files\MySQL\MySQL Server 5.5\bin\my.ini:伺服器配置檔案;
3、C:\ProgramData\MySQL\MySQL Server 5.5\dat
- 該目錄下的每個目錄表示一個數據庫,例如該目錄下有一個mysql目錄,那麼說明你的DBMS中有一個名為mysql的database;
- 在某個資料庫目錄下回有0--n個副檔名為frm的檔案,每個frm檔案表示一個table,不要用文字編輯器開啟它,它是有DBMS來讀寫的;
4、my.ini,MySQL最為重要的配置檔案
- 配置MySQL的埠,預設為3306,沒有必要時不要修改;
- 配置字元編碼:
l [client]下配置客戶端編碼:default-character-set=gbk
l [mysqld]下配置伺服器編碼:character-set-server=utf8
- 配置二進位制資料大小上限:
l 在[mysqld]下配置:max_allowed_packet=8M
2.3、伺服器操作
l 開啟伺服器(必須保證mysql為windows服務):net start mysql
檢視程序表中是否存在:mysqld.exe程序(存在)
l 關閉伺服器(必須保證mysql為windows服務):net stop mysql
檢視程序表中是否存在:mysqld.exe程序(不存在)
2.4、客戶端操作
開啟執行視窗輸入“cmd”
1、登入伺服器:mysql -uroot -proot -hlocalhost
l -u:後面跟隨使用者名稱
l -p:後面跟隨密碼
l -h:後面跟隨資料庫伺服器IP地址,localhost和127.0.0.1表示本機伺服器
2、退出伺服器:exit或quit
3、SQL語言概述
3.1、SQL簡介
1) 什麼是SQL
結構化查詢語言(Structured Query Language)。
2) SQL的作用
客戶端使用SQL來操作伺服器;
啟動mysql.exe,連線伺服器後,就可以使用sql來操作伺服器了;
將來會使用Java程式連線伺服器,然後使用sql來操作伺服器。
3) SQL標準(例如SQL99,即1999年制定的標準)
由國際標準組織(ISO)制定的,對DBMS的統一操作方式(例如相同的語句可以操作:mysql、Oracle等)。
4) SQL方言
某種DBMS不會只支援SQL標準,而且還會有一些自己獨有的語法,被稱為方言。例如limit語句只在MySQL中可以使用。
3.2、SQL語法
1) SQL語句可以在單行或多行書寫,以分號結尾;
2) 可使用空格和縮排來增強語句的可讀性;
3) MySQL不區分大小寫,建議使用大寫
3.3、SQL語句分類(重點)
1) DDL(Data Definition Language):資料定義語言,用來定義資料庫物件:對資料庫或表的結構操作(增、刪、改)。
2) DML(Data Manipulation Language):資料操作語言,用來定義資料庫記錄(資料);
對錶的記錄進行更新(增、刪、改)。
3) DCL(Data Control Language):資料控制語言,用來定義訪問許可權和安全等級;
對使用者的建立和授權。
4) DQL(Data Query Language):資料查詢語言,用來查詢記錄(資料);
主要是對錶記錄的查詢。(重點)
4、SQL操作
4.1、DDL語句
- 1. 資料庫
l 檢視所有資料庫:SHOW DATABASES
l 切換(選擇要操作的)資料庫:USE 資料庫名
l 建立資料庫:CREATE DATABASE [IF NOT EXISTS] mydb1 [CHARSET=utf8]
l 刪除資料庫:DROP DATABASE [IF EXISTS] mydb1
l 修改資料庫編碼:ALTER DATABASE mydb1 CHARACTER SET utf8
2、資料型別(列型別)
l int:整型
l double:浮點型,例如double(5,2)表示最多5位,其中必須有2為小數,即最大值為999.99;
l decimal:浮點型,在表示錢方面使用該型別,因為不會出現精度缺失問題;
l char:固定長度字串型別;char(255),資料的長度不足指定長度時,會補足到指定長度,一般用於儲存固定長度的字串,例如:身份證號,日期時間等;
l varchar:可變長度字串型別;varchar(65535),不會自動補足到指定長度,但是會至少佔用1個位元組來記錄字元長度,一般儲存姓名等;
l text(clob):字串型別,MySQL獨有型別
型別 |
長度 |
tinytext |
28-1B(256B) |
text |
216-1B(64K) |
mediumtext |
224-1B(16M) |
longtext |
232-1B(4G) |
l blob:位元組型別;
型別 |
長度 |
tinyblob |
28-1B(256B) |
blob |
216-1B(64K) |
mediumblob |
224-1B(16M) |
longblob |
232-1B(4G) |
l data:日期型別,格式為 yyyy-MM-dd;
l time:時間型別,格式為 hh:mm:ss;
l timestamp:時間戳型別;
3、表
l 建立表:
CREATE TABLE [IF NOT EXISTS] 表名(
列名 列型別,
列名 列型別,
……
列名 列型別
);
l 檢視當前資料庫中所有表名稱:SHOW TABLES;
l 檢視指定表的建立語句:SHOW CREATE TABLE 表名;
l 查看錶結構:DESC 表名;
l 刪除表:DROP TABLE 表名;
l 修改表:字首為 ALTER TABLE 表名
a) 新增列:
ALTER TABLE 表名 ADD(
列名 列型別,
列名 列型別,
……
);
b) 修改類型別(如果被修改的列已存在資料,那麼新的型別可能會影響到已存在資料):ALTER TABLE 表名 MODIFY 列名 列型別;
c) 修改列名:ALTER TABLE 表名 CHANGE 原列名 新列名 列型別;
d) 刪除列:ALTER TABLE 表名 DROP 列名;
e) 修改表名稱:ALTER TABLE 原表名 RENAME TO 新表名;
4.2、DML語句
- 1. 插入資料
l INSERT INTO 表名(列名1,列名2,...) VALUES(值1,值2,...);
在表名後給出要插入的列名,其他沒有指定的列等同於插入null值。所以插入記錄總是插入一行;
在VALUES後給出列值,值的順序和個數必須與前面指定的列對應;
在資料庫中所有的字元型別,必須使用單引號,不能使用雙引號,日期型別也要使用單引號
l INSERT INTO 表名 VALUES(列值1,值2);
沒有給出要插入的列,那麼表示插入的所有列;
值的個數必須是該表列的個數;
值的順序,必須與表建立時給出的列的順序相同。
- 2. 修改資料
l UPDATE 表名 SET 列名1=列值1,列名2=列值2,... [WHERE 條件]
l 條件(條件可選):
² 條件必須是一個boolean型別的值或表示式:UPDATE t_person SET gender='男', age=age+1 WHERE sid='1';
² 運算子:=,!=,<>,>,<,>=,<=,BETWEEN...AND,IN(...),IS NULL,NOT,OR,AND
- 3. 刪除資料
l DELETE FROM 表名 [WHERE 條件];
l TRUNCATE TABLE 表名:TRUNCATE是DDL語句,它是先刪除drop該表,再create該表,而且無法回滾。
4.3、DCL語句
- 1. 建立使用者
l CREATE USER 使用者名稱@IP地址 IDENTIFIED BY '密碼';
使用者只能在指定的IP地址上登入
l CREATE USER 使用者名稱@'%' IDENTIFIED BY '密碼';
使用者可以在任意IP地址上登入
- 2. 給使用者授權
l GRANT 許可權1,……,許可權n ON 資料庫.* TO 使用者名稱@IP地址;
給使用者分派在指定的資料庫上的指定許可權
例如:GRANT CREATE,ALTER,DROP,INSERT,UPDATE,DELETE,SELECT ON mydb1.* TO user1@localhost;
給user1使用者分派在mydb1資料庫上的CREATE、ALTER、DROP、INSERT、UPDATE、DELETE、SELECT許可權
l GRANT ALL ON 資料庫.* TO 使用者名稱@IP地址;
給使用者分派指定資料庫上的所有許可權
- 3. 撤銷授權
l REVOKE 許可權1,……,許可權n ON 資料庫.* FROM 使用者名稱@IP地址;
撤銷指定使用者在指定資料庫上的指定許可權
例如:REVOKE CREATE,ALTER,DROP ON mydb1.* FROM user1@localhost;
撤銷user1使用者在mydb1資料庫上的CREATE、ALTER、DROP許可權
- 4. 檢視許可權
l SHOW GRANTS FOR 使用者名稱@IP地址;
檢視指定使用者的許可權
- 5. 刪除使用者
l DROP USER 使用者名稱@IP地址;
4.4、DQL語句(重點)
DQL語句只會對資料庫查詢,不會修改資料。
- 1. 基本查詢
l 欄位(列)控制
² 查詢所有列
SELECT * FROM 表名;
其中“*”表示所有列
l 查詢指定列
SELECT 列1[,列2,……列n] FROM 表名;
l 完全重複的記錄只顯示一次
當查詢結果中的多行記錄完全一樣時,只顯示一行,一般用於查詢某個欄位中一共有幾種型別的值。
SELECT DISTINCT * | 列1[,列2,……,列n] FROM 表名;
例如:SELECT DISTINCT sal FROM emp;
查詢員工表的工資,如果存在相同的工資只顯示一次
l 列運算
u 數量型別的列可以做加、減、乘、除運算
SELECT *,sal*1.5 FROM emp;
字串做算術運算時,會被當做0來進行運算,在字串中+號不代表拼接
u 字串型別可以做連續運算
SELECT CONCAT('$',sal) FROM emp;
u 轉換NULL值
有時需要把NULL轉換成其他值,例如com+1000時,如果com列存在NULL值,那麼NULL+1000還是NULL,而我們這是希望把NULL當做0來運算。
SELECT IFNULL(comm,0)+1000 FROM emp;
IFNULL(comm,0):如果comm中存在NULL值,那麼當成0來運算;
u 給列起別名
當使用列運算後,查詢出的結果集中的列名稱不好看,這時我們需要給列名起個別名,這樣在結果集中列名就顯示別名了。
SELECT IFNULL(comm,0)+1000 AS 獎金 FROM emp;
其中AS可以省略
- 2. 條件控制
l 條件查詢
u 與前面介紹的UPDATE和DELETE語句一樣,SELECT語句也可以使用WHERE子句來控制記錄。
ü SELECT empno,ename,sal,comm FROM emp WHERE sal > 1000 AND comm IS NOT NULL;
ü SELECT empno,ename,sal FROM emp WHERE sal BETWEEN 20000 AND 30000;
ü SELECT empno,ename,job FROM emp WHERE job IN('經理','董事長');
l 模糊查詢
u 當你想查詢姓張,並且姓名一共兩個字的員工時,就可以使用模糊查詢
SELECT * FROM emp WHERE ename LIKE '張_';
模糊查詢需要使用運算子:LIKE,其中匹配一個任意字元,注意,只匹配一個字元而不是多個。
上面語句查詢的是姓張,名字由兩個字組成的員工。
u 下劃線“_”可以匹配1個字元,如果要匹配0-n個字元,需要用“%”;
SELECT * FROM emp WHERE ename LIKE ‘%剛’;
查詢名字結尾是帶“剛”字的員工。
- 3. 排序查詢
l 升序
u SELECT * FROM emp ORDER BY sal ASC;
按sal排序,ASC升序,DESC降序,其中ASC是可以省略的
l 降序
u SELECT * FROM emp ORDER BY comm DESC;
按comm降序排序查詢
l 使用多列作為排序條件
u SELECT * FROM emp ORDER BY sal ASC, comm DESC;
使用sal升序排序,如果sal相等,再按照comm降序排序
- 4. 聚合函式
聚合函式用來做某列的縱向運算
l COUNT()函式
SELECT COUNT(*) FROM emp;
計算emp表中所有列都不為NULL的記錄的行數
SELECT COUNT(comm) FROM emp;
計算emp表中comm列不為NULL的記錄的行數
l MAX()函式
SELECT MAX(sal) FROM emp;
查詢最高工資
l MIN()函式
SELECT MIN(sal) FROM emp;
查詢最低工資
l SUM()函式
SELECT SUM(sal) FROM emp;
查詢所有員工工資的總和
l AVG()函式
SELECT AVG(sal) FROM emp;
查詢平均工資
- 5. 分組查詢
l 分組查詢是把記錄使用某一列進行分組,然後查詢組資訊。
例如:檢視所有部門的記錄數。
SELECT deptno,COUNT(*) FROM emp GROUP BY deptno;
使用deptno分組,查詢部門編號和每個部門的記錄數
SELECT job,MAX(sal) FROM emp GROUP BY job;
使用job分組,查詢每種工作的最高工資
l 組條件
以部門分組,查詢每組記錄數,條件為記錄數大於3
SELECT deptno,COUNT(*) FROM emp GROUP BY deptno HAVING COUNT(*) > 3;
- 6. LIMIT子句(方言)
l LIMIT用來限定查詢結果的起始行,以及總行數。
例如:查詢起始行為第5行,一共查詢3行記錄
SELECT * FROM emp LIMIT 4,3;
其中4表示從第5行開始,其中3表示一共查詢3行。即第5/6/7行記錄。
l 分頁查詢中計算起始頁的公式:(當前頁-1)*每頁記錄數;
例如:每頁顯示10條記錄,查詢第3頁
SELECT * FROM emp LIMIT 20,10;
4.5、DQL語句練習
l 查詢出部門編號為30的所有員工
select * from emp where deptno=30;
l 查詢所有銷售員的姓名、編號和部門編號
select ename,empno,deptno from emp where job='銷售員';
l 查詢獎金高於工資的員工
select ename from emp where comm > sal;
l 查詢獎金高於工資60%的員工
select ename from emp where comm > sal*0.6;
l 查詢部門編號為10中所有經理,和部門編號為20中所有銷售員的詳細資料
select * from emp where (deptno = 10 and job='經理') or (deptno=20 and job='銷售員');
l 查詢部門編號為10中所有經理,部門編號為20中所有銷售員,還有既不是經理又不是銷售員但其工資大於或等於20000的所有員工資料
select * from emp where (deptno = 10 and job='經理') or (deptno=20 and job='銷售員') or (job not in ('經理','銷售員') and sal>20000);
l 查詢無獎金或獎金低於1000的員工
select * from emp where comm is null or comm<1000;
l 查詢名字由三個字組成的員工
select * from emp where ename like '___';
l 查詢2000年入職的員工
select * from emp where hiredate like '2000-%';
l 查詢所有員工詳細資訊,用編號升序排序
select * from emp order by empno asc;
l 查詢所有員工詳細資訊,用工資降序排序,如果工資相同使用入職日期升序排序
select * from emp order by sal desc,hiredate asc;
l 查詢每個部門的平均工資
select deptno,avg(*) 平均工資 from emp group by deptno;
l 查詢每個部門的僱員數量
select deptno,count(*) 數量 from emp group by deptno;
l 查詢每種工作的最高工資、最低工資、人數
select job,max(*) 最高工資,min(*) 最低工資,count(*) 人數 from emp group by job;
4、MySQL編碼問題(瞭解)
4.1、檢視MySQL資料庫編碼
SHOW VARIABLES LIKE 'char%';
4.2、編碼解釋
l character_set_client:MySQL使用該編碼來解讀客戶端傳送過來的資料,例如該編碼為utf8,那麼如果客戶端傳送過來的資料不是utf8,就會出現亂碼;
l character_set_results:MySQL會把資料轉換成該編碼後,在傳送給客戶端,例如該編碼為utf8,那麼如果客戶端不使用utf8來解讀,就會出現亂碼;
4.3、控制檯亂碼問題
l 插入或修改時出現亂碼:
這是因為cmd下預設使用GBK,而character_set_client不是GBK的原因,我們只需讓這兩個編碼相同即可;
因為修改cmd的編碼不方便,所以我們去設定character_set_client為GBK即可。
l 查詢出的資料為亂碼:
這是因為character_set_results不是GBK,而cmd預設使用GBK的原因,我們只需讓這兩個編碼相同即可;
因為修改cmd的編碼不方便,所以我們去設定character_set_results為GBK即可。
l 設定變數的語句:
set character_set_client=gbk
set character_set_results=gbk
l 這裡需要注意的是,設定變數只對當前連線有效,當退出視窗後,再次登入mysql,還需要再次設定變數。為了一勞永逸,可以在my.ini中設定: default-character-set=gbk
l 指定預設編碼
我們在安裝MySQL時已經指定了預設編碼為utf8,所以我們在建立資料庫、建立表時,都無需再次指定編碼。為了一勞永逸,可以在my.ini中設定:character-set-server=utf8
5、MySQL備份與恢復
5.1、資料庫匯出SQL指令碼(備份資料庫內容)
mysqldump -u使用者名稱 -p密碼 資料庫名>生成的指令碼檔案路徑
例如:mysqldump -uroot -proot mydb1>D:\mydb1.sql
注意,不要分號,不要登入mysql,直接在cmd下執行,生成的指令碼檔案中不包含create database語句
5.2、執行SQL指令碼(恢復資料)
l 第一種方式
mysql -u使用者名稱 -p密碼 資料庫<指令碼檔案路徑
先刪除mydb1庫,再重新建立mydb1庫,然後執行語句:
mysql -uroot -proot mydb1<D:\mydb1.sql
注意,不要使用分號,不要登入資料庫,直接在cmd下執行
l 第二種方式
登入mysql
source SQL指令碼路徑
先刪除mydb1庫,再重新建立mydb1庫,切換到mydb1庫,然後執行語句:source c:\mydb1.sql
6、MySQL約束
約束是新增在列上的,用來約束列的。
6.1、主鍵約束
主鍵約束的特點有:非空、唯一、被引用
當表的某一列被指定為主鍵後,該列就不能為空,不能有重複值出現。
- 1. 建立表時指定主鍵的兩種方式:
l 方法一:
CREATE TABLE stu(
sid CHAR(6) PRIMARY KEY,
snam VARCHAR(20),
age INT,
gender VARCHAR(10)
);
l 方法二:
指定sid列為主鍵列,即為sid列新增主鍵約束
CREATE TABLE stu(
sid CHAR(6),
sname VARCHAR(20),
gender VARCHAR(10),
PRIMARY KEY(sid)
);
指定sid列為主鍵列,即為sid列新增主鍵約束
- 修改表時指定主鍵:ALTER TABLE stu ADD PRIMARY KEY(sid);
- 刪除主鍵:ALTER TABLE stu DROP PRIMARY KEY;
- 2. 主鍵自增長
因為主鍵列的特點是:必須唯一,不能為空,所以我們通常會指定主鍵類為整型,然後設定其自動增長,這樣可以保證在插入資料時主鍵列的唯一和非空特性。
l 建立表時指定主鍵自增長
CREATE TABLE stu(
sid INT PRIMARY KEY ATUO_INCREMENT,
sname VARCHAR(20),
age INT,
gender VARCHAR(10)
);
l 修改表時設定主鍵自增長:ALTER TABLE stu CHANGE sid sid INT AUTO_INCREMENT;
l 修改表時刪除主鍵自增長:ALTER TABLE stu CHANGE sid sid INT;
l 測試主鍵自增長:
INSERT INTO stu VALUES(NULL,'zhangsan',23,'male');
INSERT INTO stu(sname,age,gender) VALUES('zhangsan',23,'male');
6.2、非空約束
因為某些列不能設定為NULL值,所以可以對列新增非空約束。
例如:
CREATE TABLE stu(
sid INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(20) NOT NULL,
age INT,
gender VARCHAR(10)
);
對sname列設定非空約束
6.3、唯一約束
車庫某些列不能設定重複的值,所以可以對列新增唯一約束。
例如:
CREATE TABLE stu(
sid INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(20) NOT NULL UNIQUE,
age INT,
gender VARCHAR(10)
);
對sname列設定了非空約束
6.4、概念模型
當我們要完成一個軟體系統時,需要把系統中的實體抽取出來,形成概念模型。
例如部門、員工都是系統中的實體。概念模型中的實體最終會成為Java中的類、資料庫中的表。
物件模型就是java中的class,關係(資料)模型就是指資料庫中的表。
在java中的三種關係是:is a、has a、use a
實體之間還存在著關係,關係有三種:
l 一對多:例如每個員工都從屬於一個部門,而一個部門可以有多個員工,其中員工是多方,部門是一方;
l 一對一:列如夫妻關係,只能是一夫一妻;
l 多對多:例如老師與學生的關係,一個老師可以有多個學生,一個學生可以有多個老師。
概念模型在Java中成為實體類(JavaBean)
類就使用成員變數來完成關係,一般都是雙向關聯,在多對一雙向中關聯,即部門中關聯員工,員工中也關聯部門。
Java的一對多
class Employee{//多方關聯一方 ... private Department department; } class Deparment{//一方關聯多方 ... private List<Employee> empList; } |
Java的一對一
class Husband{ ... private Wife wife; } class Wife{ ... private Husband husband; } |
Java多對多
class Student{ ... private List<Teacher> teaList; } class Teacher{ ... private List<Student> stuList; } |
物件模型:可以雙向關聯,而且引用的是物件,而不是一個主鍵;
關係模型:只能多方引用一方,而且引用的只是主鍵,而不是一整行記錄。
6.5、外來鍵約束
l 外來鍵必須是另一張表(或本表)的主鍵的值,外來鍵要引用主鍵;
l 外來鍵可以重複;
l 外來鍵可以為空;
l 一張表中可以有多個外來鍵;
- 資料庫多對一關係
從表中的外來鍵關聯主表的主鍵
建立主表
CREATE TABLE dept( deptno INT PRIMARY KEY AUTO_INCREMENT, dname VARCHAR(50) ); |
建立從表
CREATE TABLE emp( empno INT PRIMARY KEY AUTO_INCREMENT, ename VARCHAR(50), dno INT, CONSTRAINT fk_emp_dept FOREIGN KEY(dno) REFERENCES dept(deptno) ); |
- 資料庫一對一關係
在表中建立一對一關係比較特殊,需要讓從表的主鍵,即是主鍵又是外來鍵。
建立主表
CREATE TABLE hasband( hid INT PRIMARY KEY AUTO_INCREMENT, hname VARCHAR(50) ); |
建立從表
CREATE TABLE wife( wid INT PRIMARY KEY AUTO_INCREMENT, wname VARCHAR(50), CONSTRAINT fk_wife_hasband FOREIGN KEY(wid) REFERENCES hasband(hid) ); |
- 資料庫多對多關係
在表中建立多對多關係需要使用中間表,即需要三張表,在中間表中使用兩個外來鍵,分別引用其他兩個表的主鍵。
學生表
CREATE TABLE student( sid INT PRIMARY KEY AUTO_INCREMENT, ... ); |
老師表
CREATE TABLE teacher( tid INT PRIMARY KEY AUTO_INCREMENT, ... ); |
中間表
CREATE TABLE stu_tea( sid INT, tid INT, CONSTRAINT fk_stu_tea_sid FOREIGN KEY(sid) REFERENCES student(sid), CONSTRAINT fk_stu_tea_tid FOREIGN KEY(tid) REFERENCES teacher(tid) ); |
7、多表查詢
7.1、多表查詢的分類
l 合併結果集
l 連線查詢
l 子查詢
7.2、合併結果集
要合併的表的結果集,列型別和列數相同
UNION:去除重複行
UNION ALL:不去除重複行
例如:
SELECT * FROM ab
UNION ALL
SELECT * FROM cd;
7.3、連線查詢
- 分類
l 內連線
l 外連線
² 左外連線
² 右外連線
² 全外連線(MySQL不支援)
l 自然連線
- 內連線
l 直接查詢兩張表會得到笛卡爾集表
l 方言:SELECT * FROM 表1 別名1,表2 別名2 WHERE 別名1.xx=別名2.xx
l 標準:SELECT * FROM 表1 別名1 INNER JOIN 表2 別名2 ON 別名1.xx=別名2.xx
l 自然:SELECT * FROM 表1 別名1 NATURAL JOIN 表2 別名2
l 內連線查詢出的所有記錄都滿足條件
- 外連線
l 左外:SELECT * FROM 表1 別名1 LEFT OUTER JOIN 表2 別名2 ON 別名1.xx=別名2.xx
² 左外即左表為主,左表記錄無論是否滿足條件都會查詢出來,而右表只有滿足條件才能出來。左表不滿足條件的記錄,右表部分都為NULL
l 左外自然:SELECT * FROM 表1 別名1 NATURAL LEFT OUTER JOIN 表2 別名2 ON 別名1.xx=別名2.xx
l 右外:SELECT * FROM 表1 別名1 RIGHT OUTER JOIN 表2 別名2 ON 別名1.xx=別名2.xx
² 右表記錄無論是否滿足條件都會查詢出來,而左表只有滿足條件才能查詢出來。右表不滿足條件的記錄,其左表部分都為NULL
l 右外自然:SELECT * FROM 表1 別名1 NATURAL RIGHT OUTER JOIN 表2 別名2 ON 別名1.xx=別名2.xx
l 全連線:
在其他資料庫中使用FULL OUTER JOIN實現全連線,但是MySQL不支援,我們可以使用UNION來完成全連線;
在左外查詢語句和右外查詢語句之間加上UNION,得到左外和右外的結果集,可以間接實現全連線。
7.4、子查詢
子查詢即查詢中包含了查詢
- 出現的位置
l WHERE後作為條件存在
例如:查詢工資最高的員工的詳細資訊
SELECT * FROM emp WHERE sal=(SELECT MAX(sal) FROM emp);
l FROM後作為表存在(多行多列)
查詢30號部門員工的編號和姓名
SELECT e.empno,e.ename FROM (SELECT * FROM emp WHERE deptno=30) e;
- 條件
l 單行單列:SELECT * FROM 表1 別名1 WHERE 列1 [=、>、<、>=、<=、!=] (SELECT 列 FROM 表2 別名2 WHERE 條件);
例如:查詢大於平均工資的所有員工資訊
SELECT * FROM emp WHERE sal > (SELECT AVG(sal) FROM emp);
l 多行單列:SELECT * FROM 表1 別名1 WHERE 列1 [IN、ALL、ANY] (SELECT 列 FROM 表2 別名2 WHERE 條件);
例如:查詢大於30部門所有人工資的員工資訊
SELECT * FROM emp WHERE sal > ALL (SELECT sal FROM emp WHERE deptno=30);
l 單行多列:SELECT * FROM 表1 別名1 WHERE (列1,列2) IN (SELECT 列1,列2 FROM 表2 別名2 WHERE 條件);
例如:查詢公司裡和某員工在用一個部門並且崗位和工資都相同的員工資訊
SELECT * FROM emp WHERE (job,deptno,sal) IN (SELECT job,deptno,sal FROM emp WHERE ename='張三');
l 多行多列:SELECT * FROM 表1 別名1,(SELECT ...) 別名2 WHERE 條件;
二、Oracle資料庫
1、Oracle概述
1.1、資料庫的概念
- 資料:在資料庫領域看來,資料是儲存的基本單位,包含文字、圖片,視訊,音訊等;
- 資料庫:就是資料倉庫,儲存資料的地方,特指計算機裝置中的硬碟,以二進位制壓縮文字的形式存放。該檔案不能直接操作,必須有各資料庫公司提供的工具方可操作,該檔案的格式是每個資料庫公司定義的,不是統一規則。
- 資料庫物件:在Oracle中,例如:表、檢視、索引、函式、過程、觸發器……
- 關係型資料庫:簡單來說,以行列結構的形式,將資料庫中的資訊表示出來的物件,即二維表。
- 常見的關係型資料庫:Oracle&MySQL/DB2(IBM)/SQLServer……
1.2、Oracle資料庫伺服器組成
例項:理解為物件,看不見
資料庫:理解為類,看得見
使用例項(語句)操作資料庫
1.3、Oracle伺服器與orcl資料庫的關係
一個Oracle資料庫伺服器中包含多個數據庫,例如:orcl、orm、oa、bbs、erp等,在oradate目錄下,有多少個資料夾,就有多少個數據庫。 我們向資料庫中儲存的所有資料,最終都會存放在對應的庫*.DBF檔案中,以二進位制壓縮形式存放
1.4、使用者登陸
- 超級管理員進入:
sqlplus / as sysdba
- 普通使用者進入:
sqlplus scott/tiger
- 使用超級管理員為scott使用者解鎖和設定密碼:
解鎖使用者:alter user scott account unlock;
解鎖後使用scott使用者登陸:connect scott/tiger;
設定密碼:alter user scott identified by tiger;
使用普通使用者修改密碼使用password命令
退出工具:exit
1.5、OracleSQL和Oracle的關係
- 第四代語言:SQL(結構化查詢語言,面向關係的)
第一代:機器語言
第二代:組合語言
第三代:C/C++/C#/Java/VB……
第四代:SQL
- SQL標準的四大分類:
DML(資料操縱語言):select、insert、update、delete……
DDL(資料定義語言):create table、alter table、drop table、truncate table……
DCL(資料控制語言):grant 許可權 to scott、revoke 許可權 from scott……
事務控制語言:commit、rollback、rollback tosavepoint……
1.6、使用者與表空間
系統使用者:sys、system sys要以管理員的角色登陸
sysman 操作企業管理器
scott
登陸:[username/password] [@server] [as sysdba/sysoper]
切換使用者:connect sys/test sysdba;
檢視登陸使用者:show user
資料字典:desc dba_users
啟用scott使用者:alter user scott account unlock;
設定密碼:alter user scott identified by tiger;
查看錶空間:dba_tablespaces/user_tablespaces
1.7、解除安裝Oracle
1.開始->設定->控制面板->管理工具->服務
停止所有Oracle服務。 (執行命令:services.msc)
2.找到:C:\app\mac\product\11.2.0\dbhome_1\deinstall
執行:deinstall.bat檔案,按照提示操作
3.刪除殘留資料夾
4.執行regedit,分別刪除以下位置的Oracle入口
HKEY_LOCAL_MACHINE\SOFTWARE\ORACLE
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet002\Services\
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\
5.刪除環境變數CLASSPATH和PATH中有關Oracle的路徑
6.在C盤搜尋Oracle,刪除相關檔案
7.重啟計算機
2、Oracle實操
補充
以下程式碼是對emp表進行顯示做設定
col empno for 9999;
col ename for a10;
col job for a10;
col mgr for 9999;
col hiredate for a12;
col sal for 9999;
col comm for 9999;
col deptno for 99;
set pagesize 20;
col tname for a20;
set pagesize 80;
2.1、查詢
- 檢視當前使用者
show user;
- 查詢scott使用者下所有的表:
select * from tab;
- 查看錶結構:
desc 表名;
- 查詢某表的所有資料:
select * from 表名;
或
select 欄位名,欄位名…… from 表名;
*號是萬用字元,表示該表中的所有欄位,但*號不能和具體的欄位一起使用,在SQL語句中,大小寫不敏感,但建議大寫。
- 別名
可以使用別名查詢,使用別名後顯示的欄位名為別名,
select empno "編號",ename "姓名”… from emp;
欄位名和別名中間可以使用AS或as,使用as之後,別名可以帶引號也可以不帶引號,如果不帶引號,別名中不能有空格,單引號表示字串型別或日期型別;
- 設定表樣式,設定顯示寬度:
a) 字元型、日期型用a表示字元
column 列名 format a12; //a12表示佔12個字元
b) 數值型用9表示數字
column 列名 format 9999; //四個9表示佔4個字元
如果超過了設定的寬度會出現#號
c) 設定一頁顯示的記錄條數
set pagesize 80;
每次登陸為一次會話,exit命令為退出會話,當退出本次會話後,設定的格式都會被清除;
- 使用/槓,執行最近的一次SQL語句
- 清屏 host cls;
- 查詢表中不重複的記錄
select distinct 列名 from 表名;
- 查詢時對欄位做算術運算
select ename,sal,sal*12 "年薪" from emp; //年薪為別名
- 查詢時欄位為空
如果結果為null,在SQLplus客戶端中是不顯示的,解決null不顯示的問題,使用NVL()函式,NVL(a,b):如果a為null,則用b代替;如果a為非null,則顯示a的值,對員工表計算年收入時,可以使用以下語句:
select enamel “姓名”,sal*12+NVL(comm,0) “年收入” from emp;
- 使用dual啞表或者偽表,可以使用字串連線符號||,在Oracle中必須使用from
select ‘hello’ || ‘world’ “結果” from dual;
顯示如下格式資訊:XXX的薪水是XX美元
select ename || ‘的薪水是’ || sal || ‘美元’ from emp;
- 使用sysdate顯示系統當前時間,在預設情況下,oracle只顯示日期,而不顯示時間,格式:04-2月-15
select sysdate from dual; 或
select sysdate "日期" from dual;
- 使用spool命令,儲存SQL語句(和輸出結果)到硬碟的指定位置,並建立sql檔案
spool e:/oracle-day01.sql;
使用spool off命令,儲存SQL語句到硬碟檔案e:/oracle-day01.sql。
使用@命令,將硬碟檔案,如e:/crm.sql,讀到orcl例項中,並執行檔案中的SQL語句
@ e:/crm.sql;
- 使用 “--” 符號,設定單行註釋
--select * from emp;
使用/**/符號,設定多行註釋
/*
select * from
emp; */
- SQL語句的特點
a) 是SQL92/99的ANSI官方標準,只要按照該標準來寫,在任何的關係型資料庫中都可以直接執行;
b) SQL語句的關鍵字不能簡寫,例如:select、where、from等;
c) 大小寫不敏感,提倡大寫;
d) 能夠對錶資料進行增刪改查操作;
e) 必須以分號結束;
f) 通常稱作語句;
- SQLPLUS命令的特點
a) 是oracle自帶的一款工具,在該工具中執行的命令叫做SQLPLUS命令;
b) SQLPLUS工具的命令中關鍵字可以簡寫,例如:col enamel for a10;
c) 大小寫不敏感,提倡大寫;
d) 不能對錶資料進行增刪改查操作,只能完成顯示格式控制,例如:設定寬度、清屏、記錄執行結果等;
e) 可以不用分號結束,也可以用分號結束,建議都使用分號;
f) 通常稱作命令,是SQLPLUS工具中的命令;
2.2、where子句
- 查詢emp表中20號部門的員工資訊
select * from emp where deptno = 20;
- 查詢姓名是SMITH的員工,字串使用’’,內容大小寫敏感
select * from emp where ename = ‘SMITH’;
- 查詢1980年12月17日入職的員工,注意oracle預設日期格式(dd-mm-YY表示2位的年份)
select * from emp where hiredate = ’17-12月-80’;
- 查詢工資大於1500的員工
select * from emp where sal > 1500;
- 查詢工資不等於1500的員工【!=或<>】
select * from emp where sal <> 1500;
- 查詢薪水在1300到1600之間的員工,包括1300和1600
select * from emp where (sal>=1300) and (sal<=1600); 或
select * from emp where sal between 1300 and 1600;
- 查詢薪水不在1300到1600之間的員工,不包括1300和1600
select * from emp where sal not between 1300 and 1600;
- 查詢入職時間在“1981-2-20”到“1982-1-23”之間的員工
select * from emp where hiredate between ’20-2月-81’ and ’23-2月-82’; //日期小的在前,數字小的在前
- 查詢20號或30號部門的員工,例如:根據ID號,選中的員工,批量刪除
select * from emp where (deptno=20) or (deptno=30); 或
select * from emp where deptno in (20,30); //當條件不存在時不出錯
// in中如果是字串型別的,只能填字串型別的;如果是數字型別,可以填寫數字型別,也可以填寫能夠轉為數字的型別,如‘30’
- 查詢不是20號或30號部門的員工
select * from emp where deptno not in (20,30);
- 查詢姓名以大寫字母S開頭的員工,使用%表示0個,1個或多個字元
select * from emp where ename like ‘S%’; //不使用%等價於=精確查詢
//精確查詢用=符號,模糊查詢用like
- 查詢姓名以大寫字母N結束的員工
select * from emp where ename like ‘%N’;
- 查詢姓名第一個字母是T,最後一個字母是R的員工
select * from emp where ename like ‘T%R’;
- 查詢姓名是4個字元的員工,且第二個字元是I,使用_只能表示1個字元,不能表示0個或多個字元
select * from emp where ename like ‘_ I _ _’;
- 插入一條姓名為’T_IM’的員工,薪水1200
insert into emp (empno,ename) values (1111,’T_IM’);
- 查詢員工姓名中含有‘_’的員工,使用\轉義符,讓其後的字元迴歸本來的意思【like ‘%\_%’ escape ‘\’】
select * from emp where ename like '%\_%' escape '\'; //不一定使用斜槓
- 插入一個姓名叫 ’ 的員工
insert into emp (empno,ename) values (2222,''''); //兩個單引號表示1個單引號
- 插入一個姓名叫 ‘’ 的員工
insert into emp (empno,ename) values (3333,'''''');
- 查詢所有員工資訊,使用%或%%
select * from emp ;
select * from emp where ename like ‘%’;
select * from emp where ename like ‘%_%’;
- 查詢佣金為null的員工
select * from emp where comm is null;
//null不能參與等號運算,null能參與number/date/varchar2型別運算
- 查詢佣金為非null的員工
select * from emp where comm is not null;
- 查詢無佣金且工資大於1500的員工
select * from emp where (comm is null) and (sal > 1500);
- 查詢工資是1500或3000或5000的員工
select * from emp where sal in (1500,3000,5000);
- 查詢職位是“MANAGER”或職位不是“ANALYST”的員工(方式一,使用!=或<>)
select * from emp where (job=’MANAGER’) or (job<>’ANALYST’); //效能優於方式二
- 查詢職位是“MANAGER”或職位不是“ANALYST”的員工(方式二,使用not)
select * from emp where (job=’MANAGER’) or (not(job=’ANALYST’));
2.3、order by子句
- 查詢員工資訊(編號,姓名,月薪,年薪),按月薪升序排序,如果月薪相同,按oracle內建的校驗規則排序
select empno,ename,sal,sal*12 from emp order by sal asc; 或
select empno,ename,sal,sal*12 from emp order by sal; //預設是升序排序
- 查詢員工資訊(編號,姓名,月薪,年薪),按月薪降序排序
select empno,ename,sal,sal*12 from emp order by sal desc;
- 查詢員工資訊,按入職日期降序排序,使用列名
select empno,ename,hiredate,sal*12 "年薪"
from emp order by hiredate desc;
- order by後面可以跟列名、別名、表示式、列號(從1開始,在select子句中的列號)
select empno,ename,hiredate,sal*12 "年薪" from emp order by “年薪” desc;
select empno,ename,hiredate,sal*12 "年薪" from emp order by sal*12 desc;
select empno,ename,hiredate,sal*12 "年薪" from emp order by 4 desc;
- 查詢員工資訊,按佣金升序或降序排列,null值看成最大值
select * from emp order by comm desc;
- 查詢員工資訊,對有佣金的員工,按佣金降序排列,當order by和where同時出現時,order by在最後
select * from emp where comm is not null order by comm desc;
- 查詢員工資訊,按工資降序排列,相同工資的員工再按入職時間降序排列
select * from emp order by sal desc,hiredate desc;
- 查詢20號部門,且工資大於1500,按入職時間降序排列
select * from emp where (deptno=20) and (sal>1500)
order by hiredate desc;
2.4、單行函式
單行函式:只有一個引數輸入,只有一個結果輸出。
多行函式/分組函式:可以有多個引數輸入,只有一個結果輸出 。
- lower/upper/initcap函式,使用dual啞表
select lower(‘HELLO’) from dual; //轉小寫
select upper(‘hello’) from dual; //轉大寫
select initcap(‘hello’) from dual; //首字母大寫
- concat/substr函式
select concat(‘hello’,’world’) from dual; //連線字串,只能有兩個引數,連線多個使用管道符號
select ‘hello’ || ‘你好’ || ‘世界’ from dual; 或
select concat(‘hello’,concat(‘你好’,’世界’)) from dual;
select substr(‘hello你好’,5,3) from dual; //從第5個字元向後擷取3個字元,從1開始,表示字元,不論中英文
- length/lengthb函式
select length(‘hello你好’) from dual; //返回字串的長度
select lengthb(‘hello你好’) from dual; //返回字串的位元組長度編碼方式為UTF8/GBK,一箇中文佔3/2個位元組,一個英文佔一個位元組
- instr/lpad/rpad函式,
select instr(‘helloworld’,’o’) from dual; //字元o從左向右找第一次出現的位置,從1開始,大小寫敏感,找不到返回0
select lpad(‘hello’,10,’#’) from dual; //輸出長度為10,不足10位,向hello左邊補充#,長度小於字串長度,輸出指定長度字串(擷取後的)
select rpad(‘hello’,10,’#’) from dual; //向右邊補充#
- trim/replace函式
select trim(‘H’ from ‘hello’) from dual; //清除字串兩邊的H,返回清除後的字串,大小寫敏感
select replace(‘hello’,’l’,’L’) from dual; //把字串中的l替換為L
- round/trunc/mod函式作用於數值型
select round(3.1415,3) from dual; // 四捨五入保留3位小數
select trunc(3.1415,3) from dual; // 擷取3位小數
select mod() from dual; //取餘
- round作用於日期型(month)
select round(sysdate,’month’) from dual; //四捨五入到月,15日之前日為1,15日之後,月進1,日為1
- round作用於日期型(year)
select round(sysdate,’year’) from dual; //四捨五入到年,6月之前,月為1,日為1,6月之後,年進1,月為1,日為1
- 測試trunc作用於日期型(month)
select trunc(sysdate,’month’) from dual; //擷取到月,日為1
- 測試trunc作用於日期型(year)
select trunc(sysdate,’year’) from dual; //擷取到年,月為1,日為1
- 顯示昨天,今天,明天的日期,日期型別 +/- 數值 = 日期型別
select sysdate-1 “昨天”,sysdate “今天”,sysdate+1 “明天” from dual;
- 以年和月形式顯示員工近似工齡,日期-日期=數值
select ename “姓名”,sysdate – hiredate “入職天數” from emp;
select ename "姓名",round(sysdate - hiredate) "入職天數" from emp;
select ename "姓名",round(sysdate - hiredate,0) "入職天數" from emp;
- 使用months_between函式,精確計算到年底還有多少個月
select months_between(’31-12月-17’,sysdate) from dual; //大日期在前
- 使用months_between函式,以精確月形式顯示員工工齡
select ename “姓名”,
months_between(sysdate,hiredate) “入職月數” from emp;
- 測試add_months函式,下個月今天是多少號
select add_months(sysdate,1) from dual;
- 測試add_months函式,上個月今天是多少號
select add_months(sysdate,-1) from dual;
- 測試next_day函式
a) 從今天開始算,下一個星期三是多少號
select next_day(sysdate,’星期三’) from dual;
b) 從今天開始算,下下個星期三是多少號
select next_day(next_day(sysdate,’星期三’),’星期三’) from dual;
c) 從今天開始算,下一個星期三的下一個星期日是多少號
select next_day(next_day(sysdate,’星期三’),’星期日’) from dual;
- 測試last_day函式
d) 本月最後一天是多少號
select last_day(sysdate) from dual;
e) 本月倒數第二天是多少號
select last_day(sysdate)-1 from dual;
f) 下一個月最後一天是多少號
select last_day(add_months(sysdate,1)) from dual;
g) 上一個月最後一天是多少號
select last_day(add_months(sysdate,-1)) from dual;
- 注意:
日期 - 日期 = 天數
日期 +/- 天數 = 日期
2.5、三大型別轉換
- 隱式轉換:
varchar2 à number,例如:’123’ à 123
varchar2 à date,例如:’25-4月-15’ à ’25-4月-15’
number à varchar2,例如:123 à ‘123’
date à varchar2,例如:’25-4月-15’ à ’25-4月-15’
- oracle如何隱式轉換:
a) =號兩邊的型別是否相同
b) 如果=號兩邊的型別不同,嘗試的去做轉換
c) 在轉換時,要確保合法合理,否則轉換會失敗,例如:12月不會有32天,一年中不會有13月
- 查詢1980年12月17日入職的員工(方式一:日期隱式轉換)
select * from emp where hiredate = ’17-12月-80’;
- 日期格式的元素:
yyyy 表示年份
mm 表示月份,08
month 表示月的全稱,8月
day 表示星期幾
dd 表示日,02
時間格式 HH24:MI:SS 24小時制,12小時制在後面新增 AM/PM
- 使用to_char(日期,’格”常量”式’)函式將日期轉為字串,顯示如下格式:2015年04月25日星期六
select to_char(sysdate,'yyyy"年"mm"月"dd"日" day') from dual;
- 使用to_char(日期,‘格式’)函式將日期轉為字串,顯示格式:2015-04-25今天是星期六 15:15:15
select to_char(sysdate,'yyyy-mm-dd"今天是"day hh24:mi:ss') from dual; 或
select to_char(sysdate,'yyyy-mm-dd"今天是"day hh12:mi:ss pm') from dual;
- 使用to_char(數值,‘格式’)函式將數值轉為字串,顯示格式:$1,234.00
select to_char(1234,'$9,999.00') from dual;
- 使用to_char(數值,‘格式’)函式將數值轉為字串,顯示格式:¥1234.00
select to_char(1234,'L9999.00') from dual;
- 使用to_date(‘字串’,‘格式’)函式,查詢1980年12月17日入職的員工(方式二:日期顯示轉換)
select * from emp where
hiredate=to_date('1980年12月17日','yyyy"年"mm"月"dd"日"');
或
select * from emp where hiredate=to_date('1980-12-17','yyyy"-"mm"-"dd');
- 使用to_number(‘字串’)函式將字串‘123’轉為數字123
select to_number('123')+123 from dual; //顯示轉換,結果為246
select '123'+123 from dual; //隱式轉換,結果為246
select ‘123’ || 123 from dual; // ||符號為拼接符,結果為123123
2.6、通用函式和條件判斷
- 使用NVL(a,b)通用函式,統計員工年收入,NVL()作用於任何型別,即(number/varchar2/date),通用函式:引數型別可以是number或varchar2或date型別
select ename,sal*12+NVL(comm,0) from emp;
- 使用NVL2(a,b,c)通用函式,如果a不為NULL,取b值,否則取c值,統計員工年收入
select ename,sal*12+NVL2(comm,comm,0) from emp;
- 使用NULLIF(a,b)通用函式,在型別一致的情況下,如果a與b相同,返回NULL,否則返回a,比較10和10.0是否相同
select NULLIF(10,10.0) from dual; //結果為null,在SQLPLUS中NULL不顯示
- 使用SQL99標準通用語法中的case表示式,將職位是分析員的,工資+1000;職位是經理的,工資+800;職位是其它的,工資+400
case 欄位
when 條件 then 表示式1
when 條件 then 表示式2
else 表示式n
end
select ename “姓名”,job “職位”,sal “原工資”,
case job
when ‘ANALYST’ then sal+1000
when ‘MANAGER’ then sal+800
else sal+400
end “漲後工資”
from emp;
- 使用oracle專用語法中的decode()函式,職位是分析員的,工資+1000;職位是經理的,工資+800;職位是其它的,工資+400
decode(欄位,條件1,表示式1,條件2,表示式2,……表示式n)
select ename “姓名”,job “職位”,sal “原工資”,
decode(job,’ANALYST’,sal+1000,’MANAGER’,sal+800,sal+400)
“漲後工資”
from emp;
2.7、多行函式
- 統計emp表中員工總人數
select count(*) from emp; //*號適用於表字段較少的情況下,如果欄位多,掃描效率低,建議使用非NULL的欄位,一般用主鍵
- 統計公司有多少個不重複的部門
select count(distinct deptno) from emp;
- 統計有佣金的員工人數