一、數據場景查詢
1.1 排序
SELECT 字段名 FROM 表名 WHERE 字段=值 ORDER BY 字段名[ASC|DESC];
ASC: 升序,默認值
DESC: 降序
單列排序, 什么是單列排序:只按某一個字段進行排序,單列排序。
練習:使用年齡降序排序
組合排序,同時對多個字段進行排序,如果第 1 個字段相等,則按第 2 個字段排序,依次類推。
-- 組合排序的語法: SELECT 字段名 FROM 表名 WHERE 字段=值 ORDER BY 字段名 1 [ASC|DESC], 字段名 2 [ASC|DESC];
練習:查詢所有數據,在年齡降序排序的基礎上,如果年齡相同再以數學成績升序排序
1.2 聚合函數
之前我們做的查詢都是橫向查詢,它們都是根據條件一行一行的進行判斷,而使用聚合函數查詢是縱向查詢,它是對一列的值進行計算,然后返回一個結果值。聚合函數會忽略空值 NULL

-- 語法 SELECT 聚合函數(列名) FROM 表名;
練習:查詢學生總數
我們發現對於 NULL 的記錄不會統計,建議如果統計個數則不要使用有可能為 null 的列,但如果需要把 NULL也統計進去呢?IFNULL(列名,默認值) 如果列名不為空,返回這列的值。如果為 NULL,則返回默認值。
練習:查詢 id 字段,如果為 null,則使用 0 代替
我們可以利用 IFNULL()函數,如果記錄為 NULL,給個默認值,這樣統計的數據就不會遺漏 練習:1.3 分組
SELECT 字段 1,字段 2... FROM 表名 GROUP BY 分組字段 [HAVING 條件];

練習:
having 與 where 的區別
1.4 分頁查詢 limit的作用
INSERT INTO student3(id,NAME,age,sex,address,math,english) VALUES (9,'唐僧',25,'男','長安',87,78), (10,'孫悟空',18,'男','花果山',100,66), (11,'豬八戒',22,'男','高老庄',58,78), (12,'沙僧',50,'男','流沙河',77,88), (13,'白骨精',22,'女','白虎嶺',66,66), (14,'蜘蛛精',23,'女','盤絲洞',88,88);
limit 的作用
LIMIT 是限制的意思,所以 LIMIT 的作用就是限制查詢記錄的條數。
SELECT *|字段列表 [as 別名] FROM 表名 [WHERE 子句] [GROUP BY 子句][HAVING 子句][ORDER BY 子 句][LIMIT 子句];
練習:查詢學生表中數據,從第 3 條開始顯示,顯示 6 條。

二、數據庫表的約束
2.1 主鍵
用來唯一標識數據庫中的每一條記錄,通常不用業務字段作為主鍵,單獨給每張表設計一個 id 的字段,把 id 作為主鍵。主鍵是給數據庫和程序使用的,不是給最終的客戶使用的。所以主鍵有沒有含義沒有關系,只要不重復唯一,非空就行。
-- 在創建表的時候給字段添加主鍵 字段名 字段類型 PRIMARY KEY-- 在已有表中添加主鍵
ALTER TABLE 表名 ADD PRIMARY KEY(字段名);-- 刪除主鍵
alter table 表名 drop primary key;
練習:
1.創建一個學生st1表 字段id,name,age,把id設置為主鍵
2.添加相同主鍵看是否插入
3.刪除主鍵
注:主鍵數在一個表中,只能有一個。不能出現多個主鍵。
2.2 主鍵自增
AUTO_INCREMENT 表示自動增長(字段類型必須是整數類型)
-- 創建表時指定起始值 CREATE TABLE 表名( 列名 int primary key AUTO_INCREMENT ) AUTO_INCREMENT=起始值; -- 指定起始值為 1000-- 創建好以后修改起始值
ALTER TABLE 表名 AUTO_INCREMENT=起始值;
注:DELETE:刪除所有的記錄之后,自增長沒有影響。TRUNCATE:刪除以后,自增長又重新開始。
2.3 唯一約束
-- 唯一約束的基本格式 建表 字段名 字段類型 UNIQUE-- 建完表添加
alter table 表名 add unique(字段名)
注:null不存在數據,不屬於重復問題
2.4 非空約束
-- 非空約束的基本語法格式 字段名 字段類型 NOT NULL
2.5 默認值
在表中插入一條新記錄時,如果沒有為某個字段賦值,系統就會自動為這個字段插入默認值。
字段名 字段類型 DEFAULT 默認值
2.6 外鍵約束
CREATE TABLE emp ( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(30), age INT, dep_name VARCHAR(30), dep_location VARCHAR(30) );-- 添加數據
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('張三', 20, '研發部', '廣州');
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('李四', 21, '研發部', '廣州');
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('王五', 20, '研發部', '廣州');
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('老王', 20, '銷售部', '深圳');
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('大王', 22, '銷售部', '深圳');
INSERT INTO emp (NAME, age, dep_name, dep_location) VALUES ('小王', 18, '銷售部', '深圳');

-- 解決方案:分成 2 張表 -- 創建部門表(id,dep_name,dep_location) -- 一方,主表 create table department( id int primary key auto_increment, dep_name varchar(20), dep_location varchar(20) ); -- 創建員工表(id,name,age,dep_id) -- 多方,從表 create table employee( id int primary key auto_increment, name varchar(20), age int, dep_id int -- 外鍵對應主表的主鍵 ) -- 添加 2 個部門 insert into department values(null, '研發部','廣州'),(null, '銷售部', '深圳'); select * from department; -- 添加員工,dep_id 表示員工所在的部門 INSERT INTO employee (NAME, age, dep_id) VALUES ('張三', 20, 1); INSERT INTO employee (NAME, age, dep_id) VALUES ('李四', 21, 1); INSERT INTO employee (NAME, age, dep_id) VALUES ('王五', 20, 1); INSERT INTO employee (NAME, age, dep_id) VALUES ('老王', 20, 2); INSERT INTO employee (NAME, age, dep_id) VALUES ('大王', 22, 2); INSERT INTO employee (NAME, age, dep_id) VALUES ('小王', 18, 2); select * from employee;


-- 創建約束的語法 -- 新建表時增加外鍵: [CONSTRAINT] [外鍵約束名稱] FOREIGN KEY(外鍵字段名) REFERENCES 主表名(主鍵字段名)-- 已有表增加外鍵:
ALTER TABLE 從表 ADD [CONSTRAINT] [外鍵約束名稱] FOREIGN KEY (外鍵字段名) REFERENCES 主表(主鍵字段名);
-- 2) 創建從表 employee 並添加外鍵約束 emp_depid_fk -- 多方,從表 create table employee( id int primary key auto_increment, name varchar(20), age int, dep_id int, -- 外鍵對應主表的主鍵 -- 創建外鍵約束 constraint emp_depid_fk foreign key (dep_id) references department(id) ) -- 3) 正常添加數據 INSERT INTO employee (NAME, age, dep_id) VALUES ('張三', 20, 1); INSERT INTO employee (NAME, age, dep_id) VALUES ('李四', 21, 1); INSERT INTO employee (NAME, age, dep_id) VALUES ('王五', 20, 1); INSERT INTO employee (NAME, age, dep_id) VALUES ('老王', 20, 2); INSERT INTO employee (NAME, age, dep_id) VALUES ('大王', 22, 2); INSERT INTO employee (NAME, age, dep_id) VALUES ('小王', 18, 2); select * from employee; -- 4) 部門錯誤的數據添加失敗 -- 插入不存在的部門 -- Cannot add or update a child row: a foreign key constraint fails INSERT INTO employee (NAME, age, dep_id) VALUES ('老張', 18, 6);
刪除外鍵
ALTER TABLE 從表 drop foreign key 外鍵名稱;
然后在alter添加.....
外鍵的級聯

-- 刪除 employee 表,重新創建 employee 表,添加級聯更新和級聯刪除 drop table employee;create table employee(
id int primary key auto_increment,
name varchar(20),
age int,
dep_id int, -- 外鍵對應主表的主鍵
-- 創建外鍵約束
constraint emp_depid_fk foreign key (dep_id) references
department(id) on update cascade on delete cascade
)-- 再次添加數據到員工表和部門表
INSERT INTO employee (NAME, age, dep_id) VALUES ('張三', 20, 1);
INSERT INTO employee (NAME, age, dep_id) VALUES ('李四', 21, 1);
INSERT INTO employee (NAME, age, dep_id) VALUES ('王五', 20, 1);
INSERT INTO employee (NAME, age, dep_id) VALUES ('老王', 20, 2);
INSERT INTO employee (NAME, age, dep_id) VALUES ('大王', 22, 2);
INSERT INTO employee (NAME, age, dep_id) VALUES ('小王', 18, 2);-- 刪除部門表?能不能直接刪除?
drop table department;
-- 把部門表中 id 等於 1 的部門改成 id 等於 10
update department set id=10 where id=1;
select from employee;
select from department;
-- 刪除部門號是 2 的部門
delete from department where id=2;
三 、多表查詢
數據准備
-- 創建部門表 create table dept( id int primary key auto_increment, name varchar(20) ); insert into dept (name) values ('開發部'),('市場部'),('財務部');-- 創建員工表
create table emp (
id int primary key auto_increment,
name varchar(10),
gender char(1), -- 性別
salary double, -- 工資
join_date date, -- 入職日期
dept_id int
);
insert into emp(name,gender,salary,join_date,dept_id) values('孫悟空','男',7200,'2013-02-24',1);
insert into emp(name,gender,salary,join_date,dept_id) values('豬八戒','男',3600,'2010-12-02',2);
insert into emp(name,gender,salary,join_date,dept_id) values('唐僧','男',9000,'2008-08-08',2);
insert into emp(name,gender,salary,join_date,dept_id) values('白骨精','女',5000,'2015-10-07',3);
insert into emp(name,gender,salary,join_date,dept_id) values('蜘蛛精','女',4500,'2011-03-14',1);
笛卡爾積現象
-- 需求:查詢所有的員工和所有的部門 select * from emp,dept;
-- 設置過濾條件 Column 'id' in where clause is ambiguous select * from emp,dept where id=5; select * from emp,dept where emp.'dept_id' = dept.'id';
-- 查詢員工和部門的名字 select emp.`name`, dept.`name` from emp,dept where emp.'dept_id' = dept.'id';
3.1、內連接
-- 隱式內連接:看不到 JOIN 關鍵字,條件使用 WHERE 指定 SELECT 字段名 FROM 左表, 右表 WHERE 條件-- 顯示內連接:使用 INNER JOIN ... ON 語句, 可以省略 INNER
SELECT 字段名 FROM 左表 [INNER] JOIN 右表 ON 條件

3.2 外連接
-- 左外連接:使用 LEFT OUTER JOIN ... ON,OUTER 可以省略 SELECT 字段名 FROM 左表 LEFT [OUTER] JOIN 右表 ON 條件
-- 右外連接:使用 RIGHT OUTER JOIN ... ON,OUTER 可以省略 SELECT 字段名 FROM 左表 RIGHT [OUTER ]JOIN 右表 ON 條件
3.3、UNION
合並兩個或多個 SELECT 語句的結果。
注:UNION 內部的每個 SELECT 語句必須擁有相同數量的列。列也必須擁有相似的數據類型。同時,每個 SELECT 語句中的列的順序必須相同。
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;
UNION ALL
SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;
UNION 與 UNION ALL 區別
UNION :相同數據會不顯示 有除重功能
UNION ALL:無論數據是否重復 全部顯示
3.4、 子查詢


子查詢的結果是一個值的時候
SELECT 查詢字段 FROM 表 WHERE 字段=(子查詢);
練習:
1.查詢工資最高的員工是誰?
2.查詢工資小於平均工資的員工有哪些?
子查詢結果是多行單列的時候
SELECT 查詢字段 FROM 表 WHERE 字段 IN (子查詢);
練習:
1.查詢工資大於 5000 的員工,來自於哪些部門的名字?
2.查詢開發部與財務部所有的員工信息
子查詢的結果是多行多列
SELECT 查詢字段 FROM (子查詢) 表別名 WHERE 條件;
注:子查詢作為表需要取別名,否則這張表沒有名稱則無法訪問表中的字段
練習:
1.查詢出 2011 年以后入職的員工信息,包括部門名稱