一小時學會SQL
本篇目的是為了對資料庫操作不熟悉的同學,在較短時間內掌握資料庫的基本操作,增刪改查等操作,適合對資料庫有一定了解的同學
概述
有關資料庫概述,資料庫管理系統的基本概念介紹就不重複了,我們只需要知道 SQL是關係資料庫語言的國際標準,所以只要學會了 SQL 的操作,其他任何資料庫如 MySql Oracle 等都可以進行快速上手,我們本篇採用MySQL 資料庫進行演示
SQL 分類
DDL操作
- Data Definition Language:資料定義語言,用來定義資料庫物件,庫 表 列
- 使用關鍵字:CREATE ALERT DROP
操作資料庫
- 建立
- create database name1
- create database name1 character set gbk
- 查詢
- show database ———————– 查詢資料庫伺服器中的所有資料庫
- show create database mydb1 ——— 查詢mydb1 資料庫的定義資訊
- 修改
- alert database mydb1 character set utf8 ——————- 檢視資料庫 並修改字符集為 utf8
- 刪除
- drop database mydb1 ————————————— 刪除資料庫
DML操作
- Data Manipulation Language :資料操作語言,用來定義資料庫的記錄,對錶中的資料進行增、刪、改操作
- insert
- update
- delete
插入操作 insert
- 語法:insert into 表名 (列名1,…) values(values1,…)
- 列名與 值的 型別,個數,順序都要一一對應
- 如果要插入空值,使用 null
- 插入的日期和字元要一樣,要使用引號括起來
修改操作 update
- 語法:update 表名 set 列名1 = 值1,… where 插入的位置
刪除操作 delete
- 語法: delete from 表名 where 條件
- 還可以使用 truncate 來進行操作,truncate 是把表直接刪除掉,然後再重新建立一個同樣的新表,刪除的資料不能找回,執行速度比 delete 好,delete 刪除表中的資料,表的結構還在,資料還可以找回
DQL操作
- Data Query Language : 資料查詢語言,用來查詢資料,這是我們操作資料的重點
- 語法:
select selection_list / 要查詢的列名
from table_list / 要查詢的表名
where condition / 要查詢的條件
group by grouping_colunmns / 對查詢的條件進行分組
having condition / 分組後的行條件
order by sorting_colunmns / 對結果進行排序
limit offset_start,row_count / 對結果進行限定
- 下面我們來建立3張表來說明DQL
學生表:stu
欄位 | 型別 | 說明 |
---|---|---|
sid | char(6) | 學生學號 |
sname | varchar(50) | 學生姓名 |
age | int | 學生年齡 |
gender | varchar(50) | 學生性別 |
.sql
CREATE TABLE stu(sid char(6), sanme varchar(50),age int,gender varchar(50));
INSERT INTO stu VALUES('S_1001', 'liuYi', 35, 'male');
INSERT INTO stu VALUES('S_1002', 'chenEr', 15, 'female');
INSERT INTO stu VALUES('S_1003', 'zhangSan', 95, 'male');
INSERT INTO stu VALUES('S_1004', 'liSi', 65, 'female');
INSERT INTO stu VALUES('S_1005', 'wangWu', 55, 'male');
INSERT INTO stu VALUES('S_1006', 'zhaoLiu', 75, 'female');
INSERT INTO stu VALUES('S_1007', 'sunQi', 25, 'male');
INSERT INTO stu VALUES('S_1008', 'zhouBa', 45, 'female');
INSERT INTO stu VALUES('S_1009', 'wuJiu', 85, 'male');
INSERT INTO stu VALUES('S_1010', 'zhengShi', 5, 'female');
INSERT INTO stu VALUES('S_1011', 'xxx', NULL, NULL);
僱員表:emp
欄位 | 型別 | 說明 |
---|---|---|
empno | int | 員工編號 |
ename | varchar(50) | 員工姓名 |
job | varchar(50) | 員工工作 |
mgr | int | 領導編號 |
hiredate | date | 入職日期 |
sal | decimal(7,2) | 月薪 |
comm | decimal(7,2) | 獎金 |
deptno | int | 部門編號 |
.sql
create table emp(empno int,ename varchar(50),job varchar(50),mgr int,hiredate date,sal decimal(7,2),,comm decimal(7,2),deptno int);
INSERT INTO emp values(7369,'SMITH','CLERK',7902,'1980-12-17',800,NULL,20);
INSERT INTO emp values(7499,'ALLEN','SALESMAN',7698,'1981-02-20',1600,300,30);
INSERT INTO emp values(7521,'WARD','SALESMAN',7698,'1981-02-22',1250,500,30);
INSERT INTO emp values(7566,'JONES','MANAGER',7839,'1981-04-02',2975,NULL,20);
INSERT INTO emp values(7654,'MARTIN','SALESMAN',7698,'1981-09-28',1250,1400,30);
INSERT INTO emp values(7698,'BLAKE','MANAGER',7839,'1981-05-01',2850,NULL,30);
INSERT INTO emp values(7782,'CLARK','MANAGER',7839,'1981-06-09',2450,NULL,10);
INSERT INTO emp values(7788,'SCOTT','ANALYST',7566,'1987-04-19',3000,NULL,20);
INSERT INTO emp values(7839,'KING','PRESIDENT',NULL,'1981-11-17',5000,NULL,10);
INSERT INTO emp values(7844,'TURNER','SALESMAN',7698,'1981-09-08',1500,0,30);
INSERT INTO emp values(7876,'ADAMS','CLERK',7788,'1987-05-23',1100,NULL,20);
INSERT INTO emp values(7900,'JAMES','CLERK',7698,'1981-12-03',950,NULL,30);
INSERT INTO emp values(7902,'FORD','ANALYST',7566,'1981-12-03',3000,NULL,20);
INSERT INTO emp values(7934,'MILLER','CLERK',7782,'1982-01-23',1300,NULL,10);
部門表:dept
欄位 | 型別 | 說明 |
---|---|---|
deptno | int | 部門編號 |
dname | varchar(50) | 部門名稱 |
loc | varchar(50) | 部門地址 |
.sql
create tabal dept(deptno int,dname varchar(50),loc varchar(50));
INSERT INTO dept values(10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO dept values(20, 'RESEARCH', 'DALLAS');
INSERT INTO dept values(30, 'SALES', 'CHICAGO');
INSERT INTO dept values(40, 'OPERATIONS', 'BOSTON');
根據上面3張表,我們對這3張表進行如下操作
1 基礎查詢
- 查詢所有列:
select * from stu
- 查詢指定列:
select sid,sname,age from stu
2 條件查詢
- 就是在查詢時給出 where 字句,where 字句中使用如下的運算子以及關鍵字
- =、!=、<>、 <、<=、>、>=
- between… and
- in(set)
- is null
- and
- or
- not
- 查詢性別為女,年齡小於50的記錄:
select * from stu where gender = 'female' and age < 50;
- 查詢學號為 S_1001,或者姓名為 liSi 的記錄:
select * from stu where sid = 'S_1001' or sname = 'liSi'
- 查詢學號為 S_1001,S_1002,S1003 的記錄:
`select * from stu where sid in('S_1001','S_1002','S_1003');
- 查詢學號不是 S_1001,S_1002,S1003 的記錄:
select * from stu where sid NOT IN('S_1001','S_1002','S_1003');
- 查詢年齡為null的記錄:
SELECT * FROM stu WHERE age IS NULL;
- 查詢年齡在20到40之間的學生記錄:
*select * from stu where age between 20 and 40
*select * from stu where age >=20 and age <=40
- 查詢性別非男的學生記錄:
select * from stu where gender !='male'
select * from stu where gender <> 'male'
select * from stu where not gender ='male'
- 查詢姓名不為 null 的學生記錄
select * from stu where sname is not NULL
select * from stu where not sname is NULL
3 模糊查詢
如果我們要查詢的欄位中只包含某個欄位,我們使用 模糊查詢,使用關鍵字 LIKE ,
- _ :代表任意一個字元
- %:代表任何長度的 字元
查詢姓名由 5 個字母構成的 學生記錄:
select * from stu where sname like '_____'
- 查詢姓名由5個字母構成,並且第5個字母為“i”的學生記錄
select * from stu where sname like '____i'
;
- 查詢姓名以“z”開頭的學生記錄
select * from stu where sname like 'z%'
- 查詢姓名中包含“a”字母的學生記錄
select * from stu where sname like '%a%'
4 欄位控制查詢
重複記錄,我們查詢的結果集中可能有重複的資料,這時候使用 distinct 關鍵字來處理:
select distinct sal from emp
欄位為空,檢視 emp 表中的 月薪和 獎金之和,因為 sal 和 comm 都是數值型別,可以直接進行 加運算,反之,會出錯
select * ,sal+comm from emp
select *,sal+ IFNULL(comm,0) from emp
- 如果我們要查詢的 列 中 記錄有 NULL ,那麼使用 IFNULL 函式,把 NUL 轉換為 預設數值,上面預設 為 0
- 給列名新增 別名 : 我們可以給查詢出來的列重新起名,使用 AS 關鍵字,也可以省略
- select * ,sal + IFNULL(comm,0) as total from emp
5 排序
當我們要給查詢出的列進行排序時,可以使用 關鍵字 ORDER BY, ASC(升序,預設),DESC(降序)
- 查詢所有學生記錄,按年齡升序排序:
select * from stu order by sage ASC
select * from stu order by sage
- 查詢所有學生記錄,按年齡降序排序
select * from stu order by sage DESC
- 查詢所有僱員,按月薪降序排序,如果月薪相同時,按編號升序排序
select * from emp order by sal desc,empno asc
6 聚合函式
sum,avg,max,min,count,聚合函式是用來做縱向運算的函式
- count():統計指定列不為 NULL 的記錄行數
- max():計算指定列的最大值,如果指定的列是 字串,那麼使用字串 排序運算
- min():計算指定列的最小值
- sum():計算指定列 的數值和,如果不是數值型別,那麼 結果為 0
- avg():計算指定列的 平均值,如果不是數值型別,那麼記過為0
count: 縱向統計
- 查詢 emp 表中記錄數 :“` select count(*) from emp;
- 查詢 emp 表中有獎金的人數:
select count(comm) from emp
- 查詢 emp 表中月薪大於 2500 的人數:
select count(*) from emp where sal >2500
- 統計月薪與獎金之和大於2500元的人數
select count(*) from emp where (sal+IFNULL(comm,0))>2500
- 查詢有獎金的人數,以及所有有領導的人數
select count(comm),count(mgr) from emp
sum 和 avg : 求和 與求 平均值
- 查詢所有僱員月薪和:
select sum(sal) from emp
- 查詢所有僱員月薪和,以及所有僱員獎金和:
select sum(sal),sum(comm) from emp
- 查詢所有僱員月薪+獎金和:
select sum(sal+IFNULL(comm,0)) from emp
- 統計所有員工的平均工資:
select avg(sal) from emp
max 與 min
- 查詢最高工資和最低工資:
select max(sal),min(sal) from emp
7 分組查詢
當需要分組查詢時需要使用 group by 字句,凡是和 聚合函式同時出現的列名,要寫在 group by 之後
分組查詢
- 查詢每個部門的部門編號和每個部門的工資和
select deptno,SUM(sal) from emp group by deptno
- 查詢每個部門的部門編號以及每個部門的人數
select deptno,count(*) from emp group by deptno
- 查詢每個部門的部門編號以及每個部門工資大於1500的人數
select deptno,count(*) from emp where sal >1500 group by deptno
having 子句
- 查詢工資總和大於9000的部門編號以及工資和
select deptno,sum(sal) from emp group by deptno having sum(sal)>9000
[having 和 where 的區別:having 是在分組之後對資料進行過濾,having 後面可以使用分組函式;where 是在分組之前對資料進行過濾,where 後面不可以使用分組函式;where 是對分組前記錄的條件,如果記錄不滿足 where 的條件,那麼該資料就不會參與分組,而 having 是對分組之後的資料進行 約束]
8 limit
用來限定 查詢結果 的起始,以及總行數,適合 分頁查詢
- 查詢5行記錄,起始行從0開始
select * from emp limit 0,5
- 查詢 10行記錄,從第3行開始
select * from emp limit 3,10
總結
查詢語句 書寫順序 :select – from – where – group by – having – order by – limit
查詢語句 執行順序 :from – where – groub by – having – order by – limit
多表查詢
資料庫操作中多表查詢時很主要的,一定要熟練使用
多表查詢有如下幾種
- 合併結果集:union,union all
- 連線查詢
- 內連線:[INSERT] JOIN ON
- 外連線:OUTER JOIN ON
- 左外連線:LEFT JOIN
- 右外連線:RIGHT JOIN
- 全外連線:FULL JOIN — MySQL 不支援 全外連線
- 自然連線:NATURAL JOIN
- 子查詢
合併結果集
就是把 2 個select 語句的查詢 結果合併到一起
* UNINO :去除重複查詢,例如 :select * from t1 unino select * from t2
* UNINO ALL :不去除重複記錄,例如:select * from t1 union all select * from t2
* 要求:被合併的 2 個結果,列數,列型別 都必須相同
連線查詢
連線查詢就是求出多個表的 乘積 ,例如 t1 連線 t2 ,查詢出的 結果 就是 t1*t2,連線查詢 我們要 明白 笛卡爾積,有關笛卡爾積 的 概念就不在這裡介紹了,大家可以 自己 網上查詢
內連線
- select t1.c1,t1.c2,t2.c1 from t1,t2 where t1.c1 = t2.c1 寫為 內連線 就是 :
- select t1.c1,t1.c2,t2.c1 from t1,t2 inner join t1 on t1.c1 = t2.c1 不適用 where 而是適用 ON
外連線:查詢出的結果存在不滿足條件的可能
- select * from emp LEFT OUTER JOIN dept ON emp.deptno = dept.deptno
左外連線 是先查詢左表,然後去查詢右表,右表中滿足條件的顯示出來,不滿足條件的就顯示 NULL
右外連線 是先查詢 由表,然後去查詢 左表,左表中滿足條件顯示,不滿足 顯示 NULL
- select * from emp right outer join dept on emp.deptno = dept.deptno
連線 不一定是 2 張表,還可能是多張表,田村連線查詢我們不需要 整個 笛卡爾積,而只是需要其中的一部分,那麼這時就需要使用條件去除不需要的記錄,這個條件 一般是使用 主外來鍵 關係確定
自然連線:查詢會產生無用的笛卡爾積,使用自然連線無需 給出主外來鍵關係,自然連線會自動找到 該關係
子查詢
一個 select 語句中包含另一個 完整的 select 語句,子查詢就是巢狀 查詢,select 中包含 select ,如果一條語句中存在 2個 或多個 select ,那麼就是子查詢語句
子查詢出現的位置:
- where 後面:作為條件查詢的一部分,這種情況下,還可以使用如下關鍵字,any 、all
- from 後面:作為表的一部分
子查詢的結果集形式:
- 單行單列:用於條件
- 單行多列:用於條件
- 多行多列:用於表
- 多行單列:用於條件