DQL(條件查詢)
DQL(條件查詢)
條件查詢:
使用WHERE 子句,將不滿足條件的行過濾掉,WHERE 子句緊隨 FROM 子句。
語法:select <結果> from <表名> where <條件>
比較:=, != 或<>, >, <, >=, <=
邏輯運算
and 與
or 或
not 非
(1) 模糊查詢
LIKE :是否匹配於一個模式 一般和萬用字元搭配使用,可以判斷字元型數值或數值型.
萬用字元: % 任意多個字元,包含0個字元 _ 任意單個字元
between and 兩者之間,包含臨界值;
in 判斷某欄位的值是否屬於in列表中的某一項
IS NULL(為空的)或 IS NOT NULL(不為空的)
UNION(連線):
用的比較多union all是直接連線,取到得是所有值,記錄可能有重複 union 是取唯一值,記錄沒有重複
1、UNION 的語法如下:
[SQL 語句 1]
UNION
[SQL 語句 2]
2、UNION ALL 的語法如下:
[SQL 語句 1]
UNION ALL
[SQL 語句 2]
效率:
UNION和UNION ALL關鍵字都是將兩個結果集合併為一個,但這兩者從使用和效率上來說都有所不同。
1、對重複結果的處理:UNION在進行錶鏈接後會篩選掉重複的記錄,Union All不會去除重複記錄。
2、對排序的處理:Union將會按照欄位的順序進行排序;UNION ALL只是簡單的將兩個結果合併後就返回。
從效率上說,UNION ALL 要比UNION快很多,所以,如果可以確認合併的兩個結果集中不包含重複資料且不需要排序時的話,那麼就使用UNION ALL。
排序:
-
查詢結果排序,使用 ORDER BY 子句排序 order by 排序列 ASC/DESC
-
asc代表的是升序,desc代表的是降序,如果不寫,預設是升序
-
order by子句中可以支援單個欄位、多個欄位、表示式、函式、別名
數量限制:
-
limit子句:對查詢的顯示結果限制數目 (sql語句最末尾位置)
-
SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset;
-
SELECT * FROM table LIMIT 5;
-
SELECT * from table LIMIT 0,5;
-
SELECT * FROM table LIMIT 2 OFFSET 3;
-- 查詢語法
-- select 結果 from 表名 where 資料條件過濾 group by having order by limit
SELECT * FROM t_student
-- =在where子句後面表示 等於
SELECT * FROM t_student WHERE stu_sex='男'
SELECT * FROM t_student WHERE stu_sex!='男'
SELECT * FROM t_student WHERE stu_sex<>'男'
-- and 多個條件的並列,必須全部成立
SELECT * FROM t_student WHERE stu_score >60 AND stu_sex='女'
-- or 多個條件只要滿足一個即可
SELECT * FROM t_student WHERE stu_score >60 OR stu_sex='男'
-- 查詢成績合格的學生 >=60 <=100
SELECT * FROM t_student WHERE stu_score >=60 AND stu_score <=100
-- 列名 BETWEEN 區間開始 and 區間結束 包含60 100
SELECT * FROM t_student WHERE stu_score BETWEEN 60 AND 100
-- 模糊查詢
-- like
SELECT * FROM t_student WHERE stu_name='錦濤';
-- 查詢姓張的人
-- like '關鍵字 % _' %匹配多個字元 _只能匹配一個字元
SELECT * FROM t_student WHERE stu_name LIKE'張%';
SELECT * FROM t_student WHERE stu_name LIKE'張_';
SELECT * FROM t_student WHERE stu_name LIKE'%濤';
-- 查詢成績為80和90的學生
-- in(值1 ,值2 ...)
SELECT * FROM t_student WHERE stu_score= 80 OR stu_score=90
SELECT * FROM t_student WHERE stu_score IN(80,90,100)
-- not 不在 不是
SELECT * FROM t_student WHERE stu_score NOT IN(80,90,100)
-- 查詢性別不為空
-- is null 為null is not null 不為空
SELECT * FROM t_student WHERE stu_sex IS NULL
SELECT * FROM t_student WHERE stu_sex IS NOT NULL
/*
union 將多個查詢結果合併,要求查詢出來的列數相同
sql1
union 可以去重複元素,對結果進行排序
sql2
union / union all
*/
SELECT stu_name,stu_num FROM t_student WHERE stu_sex ='女'
UNION
SELECT stu_name,stu_num FROM t_student WHERE stu_sex ='女'
-- union all 只是粗暴的合併
SELECT stu_name,stu_num FROM t_student WHERE stu_sex ='女'
UNION ALL
SELECT stu_name,stu_num FROM t_student WHERE stu_sex ='女'
-- order by 排序
-- 預設使用主鍵 升序排列
SELECT * FROM t_student
SELECT * FROM t_student ORDER BY stu_score ASC
-- 指定排序
SELECT * FROM t_student ORDER BY stu_score DESC
-- 在條件後面加排序
SELECT * FROM t_student WHERE stu_sex='女' ORDER BY stu_score ASC
-- 行數限制
-- SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset;
-- 提取前三條資料
SELECT * FROM t_student LIMIT 3
-- 查詢成績前倆名的學生 查詢前倆條
SELECT * FROM t_student WHERE stu_score>0 ORDER BY stu_score DESC LIMIT 2
-- limit 開始位置(從0開始),數量
SELECT * FROM t_student WHERE stu_score>0 ORDER BY stu_score DESC LIMIT 0,2
-- limit 行數 offset 位置
SELECT * FROM t_student WHERE stu_score>0 ORDER BY stu_score DESC LIMIT 2 OFFSET 0
(2)分組查詢
語法:
select 分組函式,列(要求出現在group by的後面)
from 表
[where 篩選條件]
group by 分組的列表
[having 分組後的篩選]
[order by 子句]
注意:查詢列表比較特殊,要求是分組函式和group by後出現的欄位
分組查詢中的篩選條件分為兩類:
資料來源 源位置 關鍵字
-
分組前篩選 原始表 group by子句的前面 where
-
分組後篩選 分組後的結果集 group by的後面 having
-- 分組查詢 分組 會將相同內容分到同一個組 例如使用性別分組
-- 男 2
-- 女 2
-- select 結果 from 表 gronp by 分組列
-- 統計男生女生各有多少人
SELECT stu_sex,COUNT(*) FROM t_student GROUP BY stu_sex
SELECT stu_sex,MAX(stu_score) FROM t_student GROUP BY stu_sex
-- 新增查詢條件
SELECT stu_sex,COUNT(*) c
FROM t_student
WHERE stu_score>0 -- 在分組前對資料進行篩選過濾
GROUP BY stu_sex
ORDER BY c DESC -- 對分組後的結果進行排序
LIMIT 1
-- 查詢性別人數大於2的 是哪個性別 對分組後的結果進行篩選過濾
SELECT stu_sex,COUNT(*) c
FROM t_student
WHERE stu_score>0
GROUP BY stu_sex
HAVING c>=2 -- 對分組後的結果進行條件過濾
ORDER BY c DESC
(3)子查詢
含義:出現在其他語句中的select語句,稱為子查詢或內查詢;外部的查詢語句,稱為主查詢或
(1)分類:
按子查詢出現的位置:
-
select後面:僅僅支援標量子查詢
-
from後面:支援表子查詢
-
where或having後面:支援標量子查詢,列子查詢,行子查詢(較少)
-
exists後面(相關子查詢):支援表子查詢
按功能、結果集的行列數不同:
-
標量子查詢(結果集只有一行一列)
-
列子查詢(結果集只有一列多行)
-
行子查詢(結果集有一行多列)
-
表子查詢(結果集一般為多行多列)
子查詢在SELECT語句內部可以出現SELECT 語句。
語句結果可以作為外部語句中條件子句的一部分,也可以作為外部查詢的臨時表。
例如:插敘成績最高的學生資訊
-- 子查詢:出現在其他語句中的select 語句
-- 其他語句: insert ,update,delete,select
-- 在insert 語句中使用子查詢
INSERT INTO t_student(stu_name,stu_sex) SELECT stu_name,stu_sex FROM t_student WHERE stu_num=2
-- 在update 語句中使用子查詢 注意查詢的結果不能在本張表查詢
UPDATE t_student SET stu_name='王珊珊' WHERE stu_num=(SELECT stu_num FROM stu_temp WHERE stu_num=2 )
CREATE TABLE stu_temp(
stu_num INT,
stu_name VARCHAR(10)
)
-- 在select語句中使用子查詢
/*
按照子查詢結果分為
標量子查詢(一行一列)
列子查詢(一列多行)
行子查詢(一行多列)
表子查詢(多行多列)
按子查詢出現的位置:
select後面:僅僅支援標量子查詢
from後面:支援表子查詢
where或having後面:支援標量子查詢,列子查詢,行子查詢(較少)
exists後面(相關子查詢):支援表子查詢
*/
-- 在select 語句加子查詢,只能是標量子查詢
SELECT stu_name,(SELECT NOW()),stu_num FROM t_student
-- 表子查詢 八查詢結果當做一張表處理
SELECT * FROM
(SELECT stu_sex,COUNT(*) c FROM t_student GROUP BY stu_sex)t
WHERE t.c>2
-- 列子查詢
SELECT * FROM t_student
WHERE stu_socre IN(SELECT stu_score FROM t_student WHERE stu_score>50)
(4)關聯查詢–多表設計
資料冗餘-----拆分
資料庫設計正規化
-
為了建立冗餘較小、結構合理的資料庫,設計資料庫時必須遵循一定的規則。在關係型資料庫中這種規則就稱為正規化。正規化是符合某一種設計要求的總結。
-
目前關係資料庫有5種正規化:第一正規化(1NF)、第二正規化(2NF)、第三正規化(3NF)、巴斯-科德正規化(BCNF)、第四正規化(4NF)和第五正規化(5NF,又稱完美正規化)。
-
滿足最低要求的正規化是第一正規化(1NF)。在第一正規化的基礎上進一步滿足更多規範要求的稱為第二正規化(2NF),其餘正規化以次類推。一般來說,資料庫只需滿足第三正規化(3NF)就行了。
(1)第一正規化(確保每列保持原子性) 列不可再分
第一正規化是最基本的正規化。如果資料庫表中的所有欄位值都是不可分解的原子值,就說明該 資料庫表滿足了第一正規化。
(2)第二正規化
就是要有主鍵,要求其他欄位都依賴於主鍵。 沒有主鍵就沒有唯一性,沒有唯一性在集合中就定位不到這行記錄,所以要主鍵。
(3)第三正規化
就是要消除傳遞依賴,方便理解,可以看做是“消除冗餘”。
外來鍵:
引用另外一個數據表的某條記錄。
外來鍵列型別與主鍵列型別保持一致
資料表之間的關聯/引用關係是依靠具體的主鍵(primary key)和外來鍵(foreign key)建立起來的。
新增外來鍵約束語法
ALTER TABLE 表名 ADD [CONSTRAINT 約束名] FOREIGN KEY(外來鍵列) REFERENCES 關聯表(主鍵);
刪除外來鍵語法
ALTER TABLE 表名 DROP FOREIGN KEY 外來鍵約束名
注意
(1)當主表中沒有對應的記錄時,不能將記錄新增到從表
(2)不能更改主表中的值而導致從表中的記錄孤立
(3)從表存在與主表對應的記錄,不能從主表中刪除該行
(4)刪除主表前,先刪從表
/*
多表設計
設計表時:先確定儲存那類資訊,學生表,定義列,資料型別 的約束
學生表
老師表
課程表
需要儲存不同的資訊(一張表中只能儲存一類資訊)
學生表
民族,年級
老師表
民族,年級
員工表
編號,姓名,性別,部門編號
部門表
部門編號,部門名稱
學生表,年級表,課程表
表與表之間常見的幾種關係
一對一關聯(例如 一個學生只能對應一個年級)
一對多關聯(一個年級對應多個學生)
多對一關聯(多個學生對應一個年級)
多對多關聯
學生表,
學號,姓名,性別,手機號,年級編號,註冊時間
年級表,
年級編號,年級名稱,年級介紹
課程表,
課程編號,課程名稱,課程介紹
*/
DROP TABLE t_dent;
CREATE TABLE grade(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
gdesc VARCHAR(50)
)
CREATE TABLE student(
num INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
sex CHAR(1),
phone VARCHAR(11),
grade_id INT,
reg_time DATETIME
)
-- 弱關聯關係 表與表之間的關係是人為定義的,表結構中並沒有實際聯絡
-- 強關聯關係,給外來鍵新增約束,強制讓外來鍵與對應的主鍵產生關係(外來鍵 對應的都是另一個表中的主鍵)
-- 修改學生表 把gread_id設定為外來鍵 並新增約束名 指定gread_id與gread表中的id列對應
ALTER TABLE student ADD CONSTRAINT grade_id_fk FOREIGN KEY (grade_id) REFERENCES grade(id)
-- 多對多關係
-- 學生與課程的關係 一個學生對應多個課程 一個課程對應多個學生
-- 設計一個關係表,來儲存多個之間的關係
CREATE TABLE student_course(
id INT PRIMARY KEY AUTO_INCREMENT,
stu_num INT,
NAME VARCHAR(10),
course_id INT,
CONSTRAINT stu_num_fk FOREIGN KEY (stu_num) REFERENCES student(num),
CONSTRAINT course_id_fk FOREIGN KEY (course_id) REFERENCES course(id)
)
ALTER TABLE student_course DROP NAME
CREATE TABLE course(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
vdeac VARCHAR(10)
)
(4)關聯查詢–續
含義:又稱多表查詢,當查詢的欄位來自於多個表時,就會用到連線查詢
笛卡爾乘積現象:表1有m行,表2有n行,結果=m*n
-
發生原因:沒有有效的連線條件
-
如何避免:新增有效的連線條件
按功能分類:
- 內連線
等值連線
非等值連線
自連線
概念:把滿足了條件的兩張表中的交集資料查詢出來
語法:Select 結果 from 表1,表2 where 表1.column1 = 表2.column2
2.外連線
左外連線
語法:select 結果 from 表1 leftjoin 表2 on 表1.column1 = 表2.column2
右外連線
select 結果 from 表1 right join 表2 on 表1.column1 = 表2.column2
交叉連線
-- 笛卡爾乘積
SELECT
*
FROM
student,
grade -- 內連線
-- 等值連線
-- 查詢學生資訊,學號,姓名,性別,年級名稱
SELECT
student.num,
student.name,
student.sex,
grade.name
FROM
student
INNER JOIN grade
ON student.grade_id = grade.id
-- -----------
-- 為表名定義別名,然後通過別名來訪問表中的列
SELECT
s.num,
s.name,
s.sex,
s.grade_id,
g.name,
g.id
FROM
student AS s
INNER JOIN grade g
ON s.grade_id = g.id -- on 後面是倆張表關聯條件, 與where後面的條件有區別
-- 使用where條件過濾
SELECT
s.num,
s.name,
s.sex,
s.grade_id,
g.name,
g.id
FROM
student s,
grade g
WHERE s.grade_id = g.id
-- 非等值連線
ALTER TABLE student ADD score INT
-- 成績等級表
CREATE TABLE score_level(
NAME VARCHAR(10),
lower_score INT,
upper_score INT
)
SELECT
s.name,
sl.name
FROM
student s
INNER JOIN score_level sl
ON s.score BETWEEN sl.lower_score
AND sl.upper_score
-- 自連線
CREATE TABLE t_area(
id INT,
NAME VARCHAR(10),
pid INT
)
SELECT * FROM t_area t1 INNER JOIN t_area t2 ON t1.pid=t2.id
-- 外連線
-- 左外連線
ALTER TABLE student ADD CONSTRAINT FOREIGN KEY (grade_id) REFERENCES grade(id)
SELECT * FROM student s LEFT JOIN grade g ON s.grade_id=g.id
-- 右外連線
SELECT * FROM student s RIGHT JOIN grade g ON s.grade_id=g.id
-- 交叉連線
SELECT * FROM student s CROSS JOIN grade g ON s.grade_id=g.id
JOIN score_level sl
ON s.score BETWEEN sl.lower_score
AND sl.upper_score
-- 自連線
CREATE TABLE t_area(
id INT,
NAME VARCHAR(10),
pid INT
)
SELECT * FROM t_area t1 INNER JOIN t_area t2 ON t1.pid=t2.id
```mysql
-- 外連線
-- 左外連線
ALTER TABLE student ADD CONSTRAINT FOREIGN KEY (grade_id) REFERENCES grade(id)
SELECT * FROM student s LEFT JOIN grade g ON s.grade_id=g.id
-- 右外連線
SELECT * FROM student s RIGHT JOIN grade g ON s.grade_id=g.id
-- 交叉連線
SELECT * FROM student s CROSS JOIN grade g ON s.grade_id=g.id