DQL高級查詢
排序
- 語法:select … from 表名 order by 排序列 [asc|desc],排序列 [asc|desc]
asc:升序(默認是升序)desc:降序
注意:多字段排序,後面的排序是在前面排序的基礎之上的
聚合函數
作用:對一列數據進行計算,返回一個結果,忽略空值
- 語法:
- count(列名):統計一列的個數
- max(列名):求出一列的最大值
- min(列名):求出一列的最小值
- sum(列名):求出一列的總和
- avg(列名):求出一列的平均值
分組
作用:對一列數據進行分組,相同的內容分爲一組,通常與聚合函數一起使用
- 語法:select … from 表名 group by 分組列 having 分組後的過濾條件;
- where和having區別
- where在分組前進行條件過濾,不支持聚合函數
- having在分組後進行條件過濾,支持聚合函數
分頁
- 語法:select …from 表名 limit 開始索引,每頁顯示個數
- 索引特點:索引是從0開始的,默認從0開始,也可以省略
- 分頁索引公式:索引 = (當前頁-1) × 每頁個數
數據庫約束
概述
對錶中的數據進行限定,保證數據的正確性、有效性、完整性
- 分類:
- primary key:主鍵約束,要求表中有一個字段,唯一,且不能爲空,通常使用id作爲主鍵
- unique:唯一約束
- not null:非空約束
- default:默認值
- foregin key:外鍵約束
實現
主鍵約束
- 作用:限定某一列的值非空且唯一,主鍵就是表中記錄的唯一標識
- 語法:
- 創建表時設置主鍵約束
create table 表名(
id int primary key,
...
...
);
- 已有表
alter tabe 表名 add primary key(id);
- 特點:一張表只能有一個主鍵約束,但是我們可以設置聯合主鍵(多個字段)
- 自增器:atuo_increment
- 創建表時設置自增器
create table 表名(
id int priamry key auto_increment,
...
...
);
- 特點:自增器起始值爲1,可以手動指定
alter table 表名 auto_increment=起始值;
唯一約束
- 作用:限定某一列的值不能重複,可以出現多個NULL
- 語法:
- 創建表時設置唯一約束
create table 表名(
列名 數據類型 unique,
...
...
);
非空約束
- 作用:限定某一個的值不能爲NULL
- 語法:
- 創建表時設置非空約束
create table 表名(
列名 數據類型 not null,-- 非空約束
列名 數據類型 unique not null,-- (唯一+非空)
);
默認值
- 作用:限定某一列的默認值,再沒有指定的情況下所有列的默認值爲NULL
- 語法:
- 創建表設置默認值
create table 表名(
列名 數據類型 default 默認值,
...
...
);
表關係
簡稱:關係型數據庫管理系統(DBMS)
實現
一對多
- 舉例:班級和學生,多的一方來維護之間的關係【一個班級下面有多名同學,多名同學屬於某一個班級】
多對多
多對多其實是由兩個一對多組成的
- 舉例:學生和課程,創建一張中間表,在中間表中添加兩個外鍵字段,分別指向各自的主鍵,通常這兩個外鍵字段作爲聯合主鍵
【一名老師可以教導多名學生,一名學生可以被多個老師教導】
一對一
- 舉例:公民和身份證號、公司和註冊地【一個公民只能有一個身份證號,一個身份證號對應一個公民】
外鍵約束
- 作用:限定兩張表有關係的數據,保證數據的正確性、有效性和完整性
- 在從表中添加外鍵約束:
- 創建表時添加外鍵約束
create table 表名(
列名 數據類型,
[constraint] [約束名] foreign key(外鍵列) references 主表(主鍵)
);
- 給已經存在的表添加外鍵約束
alter table 表名 add [constraint] [約束名] foreign key(外鍵列) references 主表(主鍵);
- 外鍵約束特點:
- 主表不能刪除從表已引用的數據
- 從表不能添加主表未擁有的數據
- 先添加主表數據再添加從表數據
- 先刪除從表數據再刪除主表數據
- 外鍵約束允許爲空但不能是錯的
- 刪除外鍵約束:
alter table 表名 drop foreign key 約束名;
案例練習
CREATE DATABASE day19;
USE day19;
-- 創建表
CREATE TABLE student (
id INT,
NAME VARCHAR(20),
age INT,
sex VARCHAR(5),
address VARCHAR(100),
math INT,
english INT
);
-- 插入記錄
INSERT INTO student(id,NAME,age,sex,address,math,english) VALUES
(1,'馬雲',55,'男','杭州',66,78),
(2,'馬化騰',45,'男','深圳',98,87),
(3,'馬景濤',55,'男','香港',56,77),
(4,'柳焱',20,'女','湖南',76,65),
(5,'柳青',20,'男','湖南',86,NULL),
(6,'劉華',57,'男','香港',99,99),
(7,'馬德',22,'女','香港',99,99),
(8,'德瑪西亞',18,'男','南京',56,65),
(9,'唐僧',25,'男','長安',87,78),
(10,'孫悟空',18,'男','花果山',100,66),
(11,'豬八戒',22,'男','高老莊',58,78),
(12,'沙僧',50,'男','流沙河',77,88),
(13,'白骨精',22,'女','白虎嶺',66,66),
(14,'蜘蛛精',23,'女','盤絲洞',88,88);
# 排序
-- 查詢所有數據,使用年齡降序排序
SELECT *FROM student ORDER BY age DESC;
-- 查詢所有數據,在年齡降序排序的基礎上,如果年齡相同再以數學成績降序排序
SELECT *FROM student ORDER BY age DESC,math DESC;
# 聚合函數
-- 查詢學生總數(null值處理)
SELECT COUNT(*)FROM student;
-- 查詢年齡大於40的總數
SELECT COUNT(*)FROM student WHERE age>40;
-- 查詢數學成績總分
SELECT SUM(math)FROM student;
-- 查詢數學成績平均分
SELECT AVG(math) FROM student;
-- 查詢數學成績最高分
SELECT MAX(math) FROM student;
-- 查詢數學成績最低分
SELECT MIN(math) FROM student;
# 分組
-- 按性別分組
SELECT sex FROM student GROUP BY sex;
-- 查詢男女各多少人
SELECT sex,COUNT(*) FROM student GROUP BY sex;
-- 查詢年齡大於25歲的人,按性別分組,統計每組的人數
SELECT *FROM student WHERE age>25;
-- 查詢每組的人數
SELECT sex,COUNT(*) FROM student WHERE age>25 GROUP BY sex;
-- 查詢年齡大於25歲的人,按性別分組,統計每組的人數,並只顯示性別人數大於2的數據
SELECT sex,COUNT(*) FROM student WHERE age>25 GROUP BY sex HAVING COUNT(*)>2;
# 分頁
-- 查詢學生表中數據,顯示前6條
SELECT *FROM student LIMIT 0,6;
-- 查詢學生表中數據,從第三條開始顯示,顯示6條
SELECT *FROM student LIMIT 2,6;
-- 模擬百度分頁,一頁顯示5條,【索引 = (當前頁-1) × 每頁個數】
-- 第一頁
SELECT* FROM student LIMIT 0,5;
-- 第二頁
SELECT* FROM student LIMIT 5,5;
-- 第三頁
SELECT* FROM student LIMIT 10,5;
# 數據庫約束
-- 主鍵約束
-- 給student表添加主鍵約束
ALTER TABLE student ADD PRIMARY KEY(id);
-- 在創建表的時候進行主鍵約束
CREATE TABLE stu1(
id INT PRIMARY KEY,
NAME VARCHAR(25)
);
-- 在進行插入數據的時候,主鍵不可以爲空
INSERT INTO stu1 VALUE(1,'jack');
-- 聯合主鍵(主鍵字段完全相同,在進行約束的限定)
CREATE TABLE stu2(
id INT,
NAME VARCHAR(25),
PRIMARY KEY (id,NAME)
);
-- 插入數據
INSERT INTO stu2 VALUE(2,'lucy');
-- 自增器
CREATE TABLE stu3(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(25)
);
-- 插入數據
INSERT INTO stu3 VALUE(1,'tom');
INSERT INTO stu3 VALUES(10,'jack');
INSERT INTO stu3 VALUE(NULL,'tom');
-- 設置自增器的起始值
ALTER TABLE stu3 AUTO_INCREMENT=100;
INSERT INTO stu3 VALUE(NULL,'zoom');
-- 唯一約束【限定某一列的值不能重複,可以出現多個NULL】
CREATE TABLE stu4(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(25) UNIQUE
);
-- 插入數據
INSERT INTO stu4 VALUE(1,'zoom');
-- 非空約束【限定某一列的值不能爲NULL,通常與唯一約束一起使用】
-- 創建表
CREATE TABLE stu5(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(25) UNIQUE NOT NULL
);
-- 插入數據
INSERT INTO stu5 VALUE(1,'zoom');
-- 默認值【限定某一列的值,在沒有指定的情況下,所以列的默認值爲NULL】
CREATE TABLE stu6(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(25),
sex VARCHAR(25) DEFAULT '男'
);
-- 插入數據
INSERT INTO stu6 VALUE(1,'小王',NULL);
INSERT INTO stu6(id,NAME) VALUE(2,'小張');
-- 實現一對多【班級和學生】
-- 創建班級表(主表)
CREATE TABLE class(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(25)
);
-- 插入數據
INSERT INTO class VALUE(1,'一班');
INSERT INTO class VALUE(2,'二班');
-- 創建學生信息表(從表)
CREATE TABLE student1(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(32),
class_id INT -- 外鍵字段
);
-- 插入數據
INSERT INTO student1 VALUE(1,'流川楓',1);
INSERT INTO student1 VALUE(2,'櫻木花道',1);
INSERT INTO student1 VALUE(3,'大猩猩',2);
INSERT INTO student1 VALUE(4,'赤木晴子',2);
-- 通過班級查找學生信息
SELECT*FROM student1 WHERE class_id=1;
SELECT*FROM student1 WHERE class_id=2;
-- 通過學生找班級
SELECT* FROM class WHERE id=1;
SELECT* FROM class WHERE id=2;
-- 給學生表添加外鍵約束
ALTER TABLE student1 ADD CONSTRAINT class_id_fk FOREIGN KEY(class_id) REFERENCES class(id);
-- 刪除學生表的外鍵約束
ALTER TABLE student1 DROP FOREIGN KEY class_id_fk;
-- 多對多【學生和課程】
-- 課程表(主表)
CREATE TABLE course(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(32)
);
INSERT INTO course VALUES(1,'java');
INSERT INTO course VALUES(2,'ui');
INSERT INTO course VALUES(3,'美容美髮');
INSERT INTO course VALUES(4,'挖掘機');
-- 中間表(從表)
CREATE TABLE sc(
s_id INT,
c_id INT,
PRIMARY KEY(s_id,c_id)
);
-- 向中間表中插入數據
INSERT INTO sc VALUES(1,1);
INSERT INTO sc VALUES(1,2);
INSERT INTO sc VALUES(2,1);
INSERT INTO sc VALUES(2,3);
-- 聯合主鍵,可以幫助我們校驗重複選修問題
INSERT INTO sc VALUES(1,1);
-- 給中間表增外鍵約束
ALTER TABLE sc ADD CONSTRAINT s_id_fk FOREIGN KEY(s_id) REFERENCES student1(id);
ALTER TABLE sc ADD CONSTRAINT c_id_fk FOREIGN KEY(c_id) REFERENCES course(id);
-- 不可以選修,不存在的課程
INSERT INTO sc VALUES(1,7);
-- 一對一
-- 公司表
CREATE TABLE company(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(25)
);
-- 插入數據
INSERT INTO company VALUES(1,'騰訊');
INSERT INTO company VALUES(2,'百度');
-- 地址表
CREATE TABLE address(
id INT PRIMARY KEY AUTO_INCREMENT, -- 同時也作爲外鍵
NAME VARCHAR(25),
CONSTRAINT id_fk FOREIGN KEY(id) REFERENCES company(id)
);
-- 插入數據
INSERT INTO address VALUES(1,'深圳');
INSERT INTO address VALUES(2,'北京');
-- 創建數據庫
CREATE DATABASE day19_pro;
USE day19_pro;
-- 創建旅遊線路分類表
CREATE TABLE tab_category(
cid INT PRIMARY KEY AUTO_INCREMENT, -- 旅遊線路分類的主鍵
cname VARCHAR(100) NOT NULL UNIQUE -- 旅遊線路分類名稱
);
-- 添加旅遊線路分類數據
INSERT INTO tab_category (cname) VALUES ('周邊遊'),('出境遊'),('國內遊'),('港澳遊');
-- 創建旅遊線路表
CREATE TABLE tab_route(
rid INT PRIMARY KEY AUTO_INCREMENT, -- 旅遊線路主題
rname VARCHAR(100) NOT NULL UNIQUE, -- 旅遊線路名稱
price DOUBLE NOT NULL, -- 價格
cid INT NOT NULL, -- 所屬分類
CONSTRAINT to_cid_ref_cate_id FOREIGN KEY (cid) REFERENCES tab_category(cid)
);
-- 添加數據
INSERT INTO tab_route VALUES (1,'青島雙飛',19999,1);
-- 多對多關係練習
CREATE TABLE tab_user(
uid INT PRIMARY KEY AUTO_INCREMENT, -- 用戶id
username VARCHAR(200) NOT NULL UNIQUE -- 用戶名【非空+唯一】
);
-- 添加數據
INSERT INTO tab_user VALUES (NULL,'老王'),(NULL,'小王');
-- 創建收藏表
CREATE TABLE tab_favorite(
fid INT PRIMARY KEY AUTO_INCREMENT, -- 收藏主鍵
rid INT NOT NULL, -- 旅遊線路id
DATE DATE NOT NULL, -- 收藏時間
uid INT NOT NULL -- 用戶id
);
-- 給收藏表添加外鍵約束
ALTER TABLE tab_favorite ADD CONSTRAINT fa_fk FOREIGN KEY(fid) REFERENCES tab_route(rid);
ALTER TABLE tab_favorite ADD CONSTRAINT fa1_fk FOREIGN KEY(fid) REFERENCES tab_user(uid);