1. 程式人生 > >一小時學會SQL

一小時學會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 後面:作為表的一部分

子查詢的結果集形式:

  • 單行單列:用於條件
  • 單行多列:用於條件
  • 多行多列:用於表
  • 多行單列:用於條件