準備測試表,先跟著執行下麵的SQL ```sql #1.登錄MySQL後 #2.創建test_database資料庫,不存在則創建 create database if not exists test_database; #2.1.如果test_database庫存在,可以根據自己意願刪除或換個名稱 ...
準備測試表,先跟著執行下麵的SQL
#1.登錄MySQL後
#2.創建test_database資料庫,不存在則創建
create database if not exists test_database;
#2.1.如果test_database庫存在,可以根據自己意願刪除或換個名稱
drop database test_database; #刪除test_database資料庫
#3.進入剛創建的庫
use test_databsase;
#3.1.如果新建的庫存在想看庫里有沒有表
show tables;
#4.創建案例表
#4.1.創建部門表
create table DEPT(
DEPTNO int PRIMARY KEY,
DNAME VARCHAR(14) DEFAULT NULL,
LOC VARCHAR(13) DEFAULT NULL
);
#4.2.創建員工表
CREATE TABLE EMP (
EMPNO int NOT NULL,
ENAME varchar(10) DEFAULT NULL,
JOB varchar(9) DEFAULT NULL,
MGR int DEFAULT NULL,
HIREDATE date DEFAULT NULL,
SAL double(7,2) DEFAULT NULL,
COMM double(7,2) DEFAULT NULL,
DEPTNO int DEFAULT NULL,
PRIMARY KEY (`EMPNO`)
)
#5.插入數據
#5.1.給部門表插入數據
INSERT INTO
DEPT
VALUES
(0,NULL,NULL),
(10,'ACCOUNTING','NEW YORK'),
(20,'RESEARCH','DALLAS'),
(30,'SALES','CHICAGO'),
(40,'OPERATIONS','BOSTON');
#5.2.給員工表插入數據
INSERT INTO
EMP
VALUES
(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);
#6.查詢記錄
select * from DEPT;
select * from EMP;
查詢語句DQL
查詢語句的格式如下,SQL語句以分號;
為結束標記
select columns..
from table_name
where conditions;
根據conditions條件查table_name表中的符合條件數據,只檢索columns欄位(結束集也只顯示columns欄位)。
使用 * 可以展示所有的欄位。但不建議,這樣查詢量大,效率低
where子句
用於按需提取滿足條件的數據
例:查詢EMP表中部門編號為10的員工
select * from EMP where DEPTNO = 10;
SQL使用單引號標註字元串,如果使用的是數值請不要使用單引號
下麵是可以在where子句中使用的運算符
比軟運算符 | 描述 |
---|---|
= | 等於 |
<> | 不等於。註釋:在 SQL 的一些版本中,該操作符可被寫成 != |
> | 大於 |
< | 小於 |
>= | 大於等於 |
<= | 小於等於 |
邏輯運算符 | 描述 |
---|---|
AND | 同時滿足左右兩個條件的值 |
OR | 滿足左或右其中一個條件的值 |
NOT | 不滿足條件的值 |
特殊運算符 | 描述 |
---|---|
IS NULL | 表中的空值 |
BETWEEN | 在某個範圍內,配合and使用。這個要註意,必須遵循左小右大,結束集是包含兩邊的值 |
LIKE | 搜索某種模式,又稱模糊搜索。 |
IN | 指定針對某個列的多個可能值,註意這裡的值不是指一個範圍,而是明確的具體值,如:10,2,20,30;也可以搭配not使用,表示不在這個子集中 |
以下是各個運算符的案例
#比較運算符
select * from EMP where DEPTNO <> 30;
select * from EMP where DEPTNO != 10;
select * from EMP where DEPTNO > 20;
#邏輯運算符
select * from EMP where DEPTNO > 10 and DEPTNO != 30;
select * from EMP where JOB = 'SALESMAN' or JOB = 'ANALYST';
select * from EMP where not DEPTNO > 20;
#特殊運算符
select * from EMP where MGR between 7500 and 7700;
select * from EMP where ENAME in ('ALLEN','WARD');
select * from EMP where MGR is null;
like的匹配規則
通配符 | 描述 |
---|---|
% | 替代 0 個或多個字元 |
_ | 替代一個字元 |
- 使用%和_,代表占位符,其中%表示多個字元,_表示一個字元
A%
表示匹配以A開頭的任意字元串A_
表示匹配二個字元的字元串,以A開頭_A%
表示匹配二個字元的字元串是A的字元串
select * from EMP where HIREDATE like '1981-0%';
當查詢條件為0和1時,SQL會發生隱式轉換。0會轉換為false,而1即為true。
select * from student where 0;
當條件為false時,返回的結果集為空,因為表中沒有符合條件的數據
select * from student where 1;
相反當條件為true時會返回表中的所有記錄,因為表中所有記錄都滿足這個條件
除了like模糊查詢,MySQL還支持其他正則表達式匹配。使用regexp
進行正則表達式匹配
模式 | 描述 |
---|---|
^ | 匹配輸入字元串的開始位置。如果設置了 RegExp 對象的 Multiline 屬性,^ 也匹配 '\n' 或 '\r' 之後的位置。 |
$ | 匹配輸入字元串的結束位置。如果設置了RegExp 對象的 Multiline 屬性,$ 也匹配 '\n' 或 '\r' 之前的位置。 |
. | 匹配除 "\n" 之外的任何單個字元。要匹配包括 '\n' 在內的任何字元,請使用像 '[.\n]' 的模式。 |
[...] | 字元集合。匹配所包含的任意一個字元。例如, '[abc]' 可以匹配 "plain" 中的 'a'。 |
[^...] | 負值字元集合。匹配未包含的任意字元。例如, '[^abc]' 可以匹配 "plain" 中的'p'。 |
p1 | p2 |
* | 匹配前面的子表達式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。* 等價於{0,}。 |
+ | 匹配前面的子表達式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等價於 {1,}。 |
n 是一個非負整數。匹配確定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的兩個 o。 | |
m 和 n 均為非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。 |
查詢ENAME中以A開頭的記錄
select * from EMP where ENAME regexp '^A';
查詢ENAME中以R結束的記錄
select * from EMP where ENAME regexp 'R$';
查詢ENAME中包含ING的記錄
select * from EMP where ENAME regexp 'ING';
當時他們也可以聯合使用,如查詢以M開頭或N結尾的記錄
select * from EMP where ENAME regexp '^M|N$';
若存在多個條件時,把每個子條件用括弧包裹
假設要把EMP表中領導工號MGR在7800以上,並且員工部門是10和20的查詢出來。
select * from EMP where MGR > 7800 and DEPTNO = 20 or DEPTNO = 10;
以上的語句會存在把MGR > 7800 and DEPTNO = 20
當成一個子條件,再把這個子條件的結果與or DEPTNO = 10
去匹配,這樣的結果集就與原本要查詢的結果不同。存在多個子條件時應該把子條件以括弧包裹
select * from EMP where MGR > 7800 and ( DEPTNO = 20 or DEPTNO = 10 );
排序
ORDER BY
用於對結果集按照多個或一個列進行排序
SELECT columns FROM table_name ORDER BY columns [ASC|DESC];
其中 [ASC|DESC]
指定升序或降序排序,預設是ASC升序
查詢EMP,結果集按照領導工號MGR升序,如果存在同相的MGR再按照COMM降序排序
select * from EMP order by MGR asc,COMM desc;
查詢EMP,結果集按照入職時間HIREDATE升序,如果存在相同時間再按照COMM降序排序
select * from EMP order by HIREDATE asc,COMM desc;
聚合查詢
聚合查詢,也叫分組查詢是根據一個或多個列對結果集進行分組
SELECT customer_name, SUM(sales_amount) FROM sales_orders GROUP BY customer_name;
聚合查詢是指對一組數據進行統計分析,例如求和、平均值、最小值、最大值等。而聚合函數則是在執行聚合查詢時使用的函數,用於對一組數據進行彙總計算。
GROUP BY語句會將表格中指定列中相同值的行數據分為一組,然後對每組數據執行聚合函數操作(例如求和、計數等),最終將每組的數據在結果集中合併展示。因此,GROUP BY語句可以用於多個列數據的分類彙總統計
聚合函數
常用SQL自常的函數有:
- COUNT(): 計算指定列數據行數
- SUM(): 指定列數據的總和
- AVG(): 指定列數據的平均值
- MAX(): 指定列數據的最大值
- MIN(): 指定列數據的最小值
這些函數要配合group by
一起使用
統計名個部門下人數個數
select DEPTNO,count(ENAME) from EMP group by DEPTNO;
求名個部門的平均工資
select DEPTNO,AVG(SAL) from EMP group by DEPTNO;
SQL函數
與聚合函數不同,SQL不用與其他子句配合使用,他們是對列中每個值分析處理
下麵是有關數值的函數:
- ABS():返回一個數的絕對值
- CEIL():向上取整
- FLOOR():向下取整
- ROUND():四捨五入
- MOD():求兩個值的餘數
- TRUNC():截斷
下麵是對字元串二次處理的函數:
- CONCAT():連接字元串
- LENGTH():返回字元串長度
- LEFT():返回字元串左邊指定長度的子串
- RIGHT():返回字元串右邊指定長度的子串
- SUBSTRING():返回部分字元串
- LOWER():將字元串轉換為小寫字元
- UPPER():將字元串轉換為大寫字元
- TRIM():去掉字元串首尾空格或指定字元
下麵是日期和時間的函數:
- CURRENT_TIME: 返回當前時間
- CURRENT_DATE: 返回當前日期
- DAYOFWEEK():根據日期獲取星期幾
- DATEPART():返回日期的指定部分
- DATEDIFF():計算兩個日期之間的差距
其他:
- COALESCE():選擇第一個非空表達式
- NULLIF():如果兩個表達式相同,返回null,否則返回第一個表達式
- EXISTS():測試一個子查詢是否有結果集
他們中有些函數不需要參數
例:求部門平均工資,取整
select DEPTNO,CEIL(AVG(SAL)) from EMP group by DEPTNO;
select DEPTNO,FLOOR(AVG(SAL)) from EMP group by DEPTNO;
例:求部門平均工資,取餘
select DEPTNO,MOD(AVG(SAL),1) from EMP group by DEPTNO;
別名
在SQL中,表名稱或列名稱可以指定別名。這個別名不會改定原來表中的數據,只是為了加強列名稱的可讀性。
select ENAME as '員工姓名',JOB as '崗位' from EMP e;
在列名稱或表名稱後加上 as alias_name
。也可以不用顯式使用 as
,可以直接在列名或表名後跟上別名即可。
別名的作用:
- 在查詢中涉及超過一個表
- 在查詢中使用了函數
- 列名稱很長或者可讀性差
- 需要把兩個列或者多個列結合在一起
多表查詢(*JOIN連接*)
把來自兩個或多個表的行結合起來,基於這些表之間的共同欄位,把他們的結果集整合到一張表中
select
columns
from
table_name a
join
table_name b
on
a.column = b.column;
其中,
a.column = b.column
是連接條件
select e.ENAME,d.DNAME,d.LOC from EMP as e cross join DEPT as d;
多表查詢時,要用
table_name.columns
這樣的方式避免結果集的列名重覆問題;其中,cross join
可以省略,以逗號分隔student s,tencher t
上面查出來的結果集是把student表的每一條記錄都與tencher表中的記錄連接,查詢後的結果集記錄數是表A總記錄數和表B總記錄數的乘積。這樣的結果毫無意義,這種又被稱為笛卡爾積查詢。如果沒限制他們記錄連接的條件,會產生“數據爆炸”。
mysql> select e.ENAME,d.DNAME,d.LOC from EMP as e cross join DEPT as d;
+--------+------------+----------+
| ENAME | DNAME | LOC |
+--------+------------+----------+
| SMITH | OPERATIONS | BOSTON |
| SMITH | SALES | CHICAGO |
| SMITH | RESEARCH | DALLAS |
| SMITH | ACCOUNTING | NEW YORK |
| SMITH | NULL | NULL |
| ALLEN | OPERATIONS | BOSTON |
| ALLEN | SALES | CHICAGO |
| ALLEN | RESEARCH | DALLAS |
| ALLEN | ACCOUNTING | NEW YORK |
| ALLEN | NULL | NULL |
| WARD | OPERATIONS | BOSTON |
| WARD | SALES | CHICAGO |
| WARD | RESEARCH | DALLAS |
| WARD | ACCOUNTING | NEW YORK |
| WARD | NULL | NULL |
| JONES | OPERATIONS | BOSTON |
| JONES | SALES | CHICAGO |
| JONES | RESEARCH | DALLAS |
| JONES | ACCOUNTING | NEW YORK |
| JONES | NULL | NULL |
| MARTIN | OPERATIONS | BOSTON |
| MARTIN | SALES | CHICAGO |
| MARTIN | RESEARCH | DALLAS |
| MARTIN | ACCOUNTING | NEW YORK |
| MARTIN | NULL | NULL |
| BLAKE | OPERATIONS | BOSTON |
| BLAKE | SALES | CHICAGO |
| BLAKE | RESEARCH | DALLAS |
| BLAKE | ACCOUNTING | NEW YORK |
| BLAKE | NULL | NULL |
| CLARK | OPERATIONS | BOSTON |
| CLARK | SALES | CHICAGO |
| CLARK | RESEARCH | DALLAS |
| CLARK | ACCOUNTING | NEW YORK |
| CLARK | NULL | NULL |
| SCOTT | OPERATIONS | BOSTON |
| SCOTT | SALES | CHICAGO |
| SCOTT | RESEARCH | DALLAS |
| SCOTT | ACCOUNTING | NEW YORK |
| SCOTT | NULL | NULL |
| KING | OPERATIONS | BOSTON |
| KING | SALES | CHICAGO |
| KING | RESEARCH | DALLAS |
| KING | ACCOUNTING | NEW YORK |
| KING | NULL | NULL |
| TURNER | OPERATIONS | BOSTON |
| TURNER | SALES | CHICAGO |
| TURNER | RESEARCH | DALLAS |
| TURNER | ACCOUNTING | NEW YORK |
| TURNER | NULL | NULL |
| ADAMS | OPERATIONS | BOSTON |
| ADAMS | SALES | CHICAGO |
| ADAMS | RESEARCH | DALLAS |
| ADAMS | ACCOUNTING | NEW YORK |
| ADAMS | NULL | NULL |
| JAMES | OPERATIONS | BOSTON |
| JAMES | SALES | CHICAGO |
| JAMES | RESEARCH | DALLAS |
| JAMES | ACCOUNTING | NEW YORK |
| JAMES | NULL | NULL |
| FORD | OPERATIONS | BOSTON |
| FORD | SALES | CHICAGO |
| FORD | RESEARCH | DALLAS |
| FORD | ACCOUNTING | NEW YORK |
| FORD | NULL | NULL |
| MILLER | OPERATIONS | BOSTON |
| MILLER | SALES | CHICAGO |
| MILLER | RESEARCH | DALLAS |
| MILLER | ACCOUNTING | NEW YORK |
| MILLER | NULL | NULL |
+--------+------------+----------+
70 rows in set (0.00 sec)
內連接(交叉連接)
內連接是多表查詢中最常用的連接操作。
select * from EMP e inner join DEPT d;
在多表查詢中使用 on
子句,限制連接條件,從而避免產生笛卡爾積
select
e.ENAME,d.DNAME,d.LOC
from
EMP as e
cross join
DEPT as d
on
e.DEPTNO = d.DEPTNO;
當EMP表DEPTNO欄位的值等於DEPT表DEPTNO的值時,兩條記錄才能連接
where和on的區別。on是在連接時指定的條件,當條件滿足時,兩條記錄才會建立連接;where則是在連接後用於過濾結果集的,使用where還是會存笛卡爾積現象。
where和on可以配合使用
select
*
from
EMP as e
cross join
DEPT as d
on
e.DEPTNO = d.DEPTNO
where
e.SAL > 2000;
當滿足 e.DEPTNO = d.DEPTNO
時記錄才能連接,對連接後的結果集過濾 e.SAL > 2000
左連接
左連接 left join
又叫左外連接,意思是把join
左邊表的全部記錄與右表中符合條件的記錄連接,右表中沒有滿足匹配條件的記錄,左表的記錄照樣展示,但對應右表的記錄即為null
select
*
from
EMP e
left join
DEPT d
on
d.DEPTNO = e.DEPTNO;
左連接就是把left join
左邊的表所有的記錄都拿出來,然後把符合 on
條件的右表記錄與左表的記錄拼接。如果左表的記錄在右表中沒有符合的記錄,那麼,其右表的記錄表達方式則為null
。
也就是join左邊的表記錄必須展示,而右表則是按需on
展示拼接。
右連接
右連接 right join
也叫右外連接。和左外連接相同,左邊表沒有符合條件的則以null
方式展示。
select
*
from
EMP e
right join
DEPT d
on
d.DEPTNO = e.DEPTNO;
右連接就是把right join
右邊表的所有記錄與左表符合條件 on
的拼接。左表沒有符合條件的以null
展示。上圖中,第一條和最後一條,由於EMP
表中沒有DEPTNO=0
和DEPTNO=40
的記錄,所以左邊的記錄顯示為NULL
全連接
全連接 full join
,是把兩個表相互匹配,也就是左連接和右連接的記錄組合在一個表中展示。目前MySQL不支持全連接
select
*
from
EMP e
full join
DEPT d
on
d.DEPTNO = e.DEPTNO;
+------+------+------+---------+----------+------+-------+----------+
| id | name | age | country | class_id | id | name | class_id |
+------+------+------+---------+----------+------+-------+----------+
| 1 | chen | 16 | CN | 10-05 | 11 | zhang | 10-05 |
| 2 | chen | 17 | CN | 10-05 | 11 | zhang | 10-05 |
| 3 | ji | 18 | US | 11-05 | 12 | zhong | 11-05 |
| 4 | ci | 17 | JP | 12-02 | 9 | wen | 12-02 |
| 5 | li | 17 | CN | 11-01 | 7 | li | 11-01 |
| 6 | en | 18 | US | 11-02 | NULL | NULL | NULL |
| 7 | wan | 17 | JP | 12-07 | NULL | NULL | NULL |
| 8 | kan | 17 | CN | 12-08 | NULL | NULL | NULL |
| 9 | suo | 18 | US | 11-01 | 7 | li | 11-01 |
| 10 | ge | 17 | JP | 10-08 | NULL | NULL | NULL |
| 9 | suo | 18 | US | 11-01 | 7 | li | 11-01 |
| 5 | li | 17 | CN | 11-01 | 7 | li | 11-01 |
| NULL | NULL | NULL | NULL | NULL | 8 | lin | 11-08 |
| 4 | ci | 17 | JP | 12-02 | 9 | wen | 12-02 |
| NULL | NULL | NULL | NULL | NULL | 10 | huen | 10-11 |
| 2 | chen | 17 | CN | 10-05 | 11 | zhang | 10-05 |
| 1 | chen | 16 | CN | 10-05 | 11 | zhang | 10-05 |
| 3 | ji | 18 | US | 11-05 | 12 | zhong | 11-05 |
+------+------+------+---------+----------+------+-------+----------+
union操作符
用於合併多個select
語句的結果。要註意,多個select
語句必須要擁有相同數量的欄位,欄位的數據類型也要相似。
select id,name,class_id from studet
union
select id,name,class_id from tencher;
如果多個查詢語句的欄位數不同,則提示
ERROR 1222 (21000): The used SELECT statements have a different number of columns
limit
分頁查詢,如果查詢到的記錄過多時,可以分頁顯示
select * from EMP limit 5;
查詢結果顯示前5條記錄
還可以指定從哪條記錄開始顯示
select * from EMP limit 0,5;
從第一條記錄開始顯示,向後展示5條記錄。
通用的分頁公式
limit ((pageNo - 1) * pageSize) , pageSize
pageNo要從哪條數據開始,pageSize每頁多少條數據