DQL查詢資料
阿新 • • 發佈:2021-07-12
DQL查詢資料
DQL
(Data Query Language:資料查詢語言)
- 所有的查詢操作都用它 Select
- 簡單的查詢,複雜的查詢它都能做
- 資料庫中最核心的語言,最重要的語句
- 使用頻率最高的語句
select完整語法:
SELECT [ALL | DISTINCT] {* | table.* | [table.field1[AS alias1]][,table.field1[AS alias2]][,....]} FROM table_name [AS table_alias] [LEFT | RIGHT | INNER JOIN table_name2] -- 聯合查詢 [WHERE ...} -- 指定結果需要滿足的條件 [GROUP BY .....] -- 指定結果按照哪幾個欄位來分組 [HAVING] -- 過濾分組的記錄必須滿足的次要條件 [ORDER BY ...] -- 指定查詢記錄按一個或多個條件排序 [LIMIT {[OFFSET,] ROW_COUNT | rou_countoffset OFFSET}]; -- 指定查詢的記錄從那條至哪條
注意:[ ]括號代表可選的,{ }括號代表必選的
CREATE DATABASE IF NOT EXISTS `school` -- 建立一個school資料庫 USE `school`;-- 建立學生表 DROP TABLE IF EXISTS `student`; CREATE TABLE `student`( `studentno` INT(4) NOT NULL COMMENT '學號', `loginpwd` VARCHAR(20) DEFAULT NULL, `studentname` VARCHAR(20) DEFAULT NULL COMMENT '學生姓名', `sex` TINYINT(1) DEFAULT NULL COMMENT '性別,0或1', `gradeid` INT(11) DEFAULT NULL COMMENT '年級編號', `phone` VARCHAR(50) NOT NULL COMMENT '聯絡電話,允許為空', `address` VARCHAR(255) NOT NULL COMMENT '地址,允許為空', `borndate` DATETIME DEFAULT NULL COMMENT '出生時間', `email` VARCHAR (50) NOT NULL COMMENT '郵箱賬號允許為空', `identitycard` VARCHAR(18) DEFAULT NULL COMMENT '身份證號', PRIMARY KEY (`studentno`), UNIQUE KEY `identitycard`(`identitycard`), KEY `email` (`email`) )ENGINE=MYISAM DEFAULT CHARSET=utf8; -- 建立年級表 DROP TABLE IF EXISTS `grade`; CREATE TABLE `grade`( `gradeid` INT(11) NOT NULL AUTO_INCREMENT COMMENT '年級編號', `gradename` VARCHAR(50) NOT NULL COMMENT '年級名稱', PRIMARY KEY (`gradeid`) ) ENGINE=INNODB AUTO_INCREMENT = 6 DEFAULT CHARSET = utf8; -- 建立科目表 DROP TABLE IF EXISTS `subject`; CREATE TABLE `subject`( `subjectno`INT(11) NOT NULL AUTO_INCREMENT COMMENT '課程編號', `subjectname` VARCHAR(50) DEFAULT NULL COMMENT '課程名稱', `classhour` INT(4) DEFAULT NULL COMMENT '學時', `gradeid` INT(4) DEFAULT NULL COMMENT '年級編號', PRIMARY KEY (`subjectno`) )ENGINE = INNODB AUTO_INCREMENT = 19 DEFAULT CHARSET = utf8; -- 建立成績表 DROP TABLE IF EXISTS `result`; CREATE TABLE `result`( `studentno` INT(4) NOT NULL COMMENT '學號', `subjectno` INT(4) NOT NULL COMMENT '課程編號', `examdate` DATETIME NOT NULL COMMENT '考試日期', `studentresult` INT (4) NOT NULL COMMENT '考試成績', KEY `subjectno` (`subjectno`) )ENGINE = INNODB DEFAULT CHARSET = utf8; -- 插入學生資料 其餘自行新增 這裡只添加了2行 INSERT INTO `student` (`studentno`,`loginpwd`,`studentname`,`sex`,`gradeid`,`phone`,`address`,`borndate`,`email`,`identitycard`) VALUES (1000,'123456','張偉',0,2,'13800001234','北京朝陽','1980-1-1','[email protected]','123456198001011234'), (1001,'123456','趙強',1,3,'13800002222','廣東深圳','1990-1-1','[email protected]','123456199001011233'); -- 插入成績資料 這裡僅插入了一組,其餘自行新增 INSERT INTO `result`(`studentno`,`subjectno`,`examdate`,`studentresult`) VALUES (1000,1,'2013-11-11 16:00:00',85), (1000,2,'2013-11-12 16:00:00',70), (1000,3,'2013-11-11 09:00:00',68), (1000,4,'2013-11-13 16:00:00',98), (1000,5,'2013-11-14 16:00:00',58); -- 插入年級資料 INSERT INTO `grade` (`gradeid`,`gradename`) VALUES(1,'大一'),(2,'大二'),(3,'大三'),(4,'大四'),(5,'預科班'); -- 插入科目資料 INSERT INTO `subject`(`subjectno`,`subjectname`,`classhour`,`gradeid`)VALUES (1,'高等數學-1',110,1), (2,'高等數學-2',110,2), (3,'高等數學-3',100,3), (4,'高等數學-4',130,4), (5,'C語言-1',110,1), (6,'C語言-2',110,2), (7,'C語言-3',100,3), (8,'C語言-4',130,4), (9,'Java程式設計-1',110,1), (10,'Java程式設計-2',110,2), (11,'Java程式設計-3',100,3), (12,'Java程式設計-4',130,4), (13,'資料庫結構-1',110,1), (14,'資料庫結構-2',110,2), (15,'資料庫結構-3',100,3), (16,'資料庫結構-4',130,4), (17,'C#基礎',130,1);
指定查詢欄位
-- 查詢全部的學生 : Select 欄位 from 表
SELECT * FROM student
-- 查詢指定的欄位
SELECT `studentno`,`studentname` FROM student
-- 別名,給結果起一個名字 AS 可以給欄位起別名,也可以給表起別名
SELECT `studentno` AS 學號,`studentname` AS 姓名 FROM student
-- 函式 concat(A,B)
SELECT CONCAT('姓名:',`studentname`) AS 新名字 FROM student
語法:Select 欄位.... from 表
有的時候,列名字不是那麼的見名知意,我們起別名
AS
欄位名 as 別名
表名 as 別名
去重 distinct
作用:去除select查詢出來的結果中重複的結果,重複的只顯示一條
-- 查詢一下有哪些同學參加了考試,成績
SELECT * FROM result -- 查詢全部考試的成績
SELECT `studentno` FROM result -- 查詢有哪些同學參加了考試
SELECT DISTINCT `studentno` FROM result
資料庫的列(表示式)
SELECT
version() -- 查詢系統版本(函式)
SELECT
100-3 * 54 AS 計算結果 -- 用來計算 (表示式)
SELECT
@@auto_increment_increment -- 查詢自增的步長(變數)
資料庫中的表示式:文字值、列、Null、函式、計算表示式、系統變數…
Select 表示式
from 表
where條件語句
作用:檢索資料符合條件
的值
搜尋的條件由一個或者多個表示式組成!結果 布林值
邏輯運算子
運算子 | 語法 | 描述 |
---|---|---|
and && | a and b a&&b | 邏輯與,兩個都為真,結果為真 |
or || | a or b a||b | 邏輯或,其中一個為真,結果為真 |
Not ! | not a !a | 邏輯非,真為假,假為真 |
儘量使用英文字母
-- ========================================= where ==================
SELECT `studentno`,`studentresult` FROM result
-- 查詢考試成績在95-100分之間
SELECT `studentno`,`studentresult` FROM result
WHERE studentresult>=95 AND studentresult<=100
-- and &&
SELECT `studentno`,`studentresult` FROM result
WHERE studentresult>=95 && studentresult<=100
-- 模糊查詢(區間)
SELECT `studentno`,`studentresult` FROM result
WHERE studentresult BETWEEN 95 AND 100
-- 除了10號學生之外的同學成績
SELECT `studentno`,`studentresult` FROM result
WHERE studentno!=10
-- != not
SELECT `studentno`,`studentresult` FROM result
WHERE NOT studentno=10
模糊查詢:比較運算子
運算子 | 語法 | 描述 |
---|---|---|
IS NULL | a is null | 如果操作為NULL,結果為真 |
IS NOT NULL | a is not null | 如果操作不為NULL,結果為真 |
BETWEEN | a between b and c | 若a在b和c之間,則結果為真 |
Like | a like b | SQL匹配,如果a匹配b,則結果為真 |
In | a in(a1,a2,a3…) | 假設a在a1,或者a2…其中的某一個值中,結果為真 |
-- =============== 模糊查詢 ===================
-- 查詢姓張的同學
-- like結合 %(代表0到任意個字元) _(一個字元)
SELECT `studentno`,`studentname` FROM `student`
WHERE `studentname` LIKE '張%'
-- 查詢姓張的同學,名字後面只有一個字
SELECT `studentno`,`studentname` FROM `student`
WHERE `studentname` LIKE '張_'
-- 查詢姓張的同學,名字後面只有兩個字的
SELECT `studentno`,`studentname` FROM `student`
WHERE `studentname` LIKE '張__'
-- 查詢名字中間有佳字的同學 %佳%
SELECT `studentno`,`studentname` FROM `student`
WHERE `studentname` LIKE '%佳%'
-- ============ in (具體的一個或者多個值) ===============
-- 查詢 1001,1002,1003 號學員
SELECT `studentno`,`studentname` FROM `student`
WHERE `studentno` IN (1001,1002,1003)
-- 查詢在北京的同學
SELECT `studentno`,`studentname` FROM `student`
WHERE `address` IN ('北京')
-- ================ null not null ===========
-- 查詢地址為空的學生 null ''
SELECT `studentno`,`studentname` FROM `student`
WHERE `address`='' OR `address` IS NULL
-- 查詢出生日期的同學 不為空
SELECT `studentno`,`studentname` FROM `student`
WHERE `borndate` IS NOT NULL
-- 查詢沒有出生日期的同學 為空
SELECT `studentno`,`studentname` FROM `student`
WHERE `borndate` IS NULL
聯表查詢
JOIN 對比
操作 | 描述 |
---|---|
Inner join | 如果表中至少有一個匹配,就返回行 |
left join | 會從左表中返回所有的值,即使右表中沒有匹配 |
right join | 會從右表中返回所有的值,即使左表中沒有匹配 |
-- =============== 聯表查詢JOIN ==================
-- 查詢參加了考試的同學(學號、姓名、科目編號、分數)
SELECT * FROM student
SELECT * FROM result
/*思路
1、分析需求,分析查詢的欄位來自哪些表(連線查詢)
2、確定使用哪種連線查詢? 7中
確定交叉點(這兩個表中哪個資料是相同的)
判斷的條件:學生表中 studentNo = 成績表 studentno
*/
-- join (連線的表) on (判斷的條件) 連線查詢
-- where 等值查詢
SELECT s.studentno,studentname,`subjectno`,`studentresult`
FROM student AS s
INNER JOIN result AS r
WHERE s.studentno = r.studentno
SELECT s.studentno,studentname,`subjectno`,`studentresult`
FROM student AS s
INNER JOIN result AS r
ON s.studentno = r.studentno
-- right join
SELECT s.studentno,studentname,`subjectno`,`studentresult`
FROM student AS s
RIGHT JOIN result AS r
ON s.studentno = r.studentno
-- left join
SELECT s.studentno,studentname,`subjectno`,`studentresult`
FROM student AS s
LEFT JOIN result AS r
ON s.studentno = r.studentno
-- 查詢缺考的同學
SELECT s.studentno,studentname,`subjectno`,`studentresult`
FROM student AS s
LEFT JOIN result AS r
ON s.studentno = r.studentno
WHERE studentresult IS NULL
-- 思考題(查詢了參加考試的同學資訊:學號,學生姓名,科目名,分數)
/*思路
1、分析需求,分析查詢的欄位來自哪些表,student、result、subject(連線查詢)
2、確定使用哪種連線查詢? 7中
確定交叉點(這兩個表中哪個資料是相同的)
判斷的條件:學生表中 studentNo = 成績表 studentno
*/
-- right join
SELECT s.studentno,studentname,`subjectname`,`studentresult`
FROM student AS s
RIGHT JOIN result AS r
ON s.studentno = r.studentno
INNER JOIN `subject` sub
ON r.subjectno = sub.subjectno
-- 我要查詢哪些資料 select ....
-- 從那幾個表中查 FROM 表 xxx join 連線的表 on 交叉檔案
-- 假設存在一種多張表查詢,慢慢來,先查詢兩張表然後再慢慢增加
自連線
自己的表和自己的表連線,核心:一張表拆分為兩張一樣的表即可
父類:
categoryid | categoryName |
---|---|
2 | 資訊科技 |
3 | 軟體開發 |
5 | 美術設計 |
子類:
pid | categoryid | categoryName |
---|---|---|
3 | 4 | 資料庫 |
2 | 8 | 辦公資訊 |
3 | 6 | web開發 |
5 | 7 | ps技術 |
操作:查詢父類對應的子類關係
父類 | 子類 |
---|---|
資訊科技 | 辦公資訊 |
軟體開發 | 資料庫 |
軟體開發 | web開發 |
美術設計 | ps技術 |
-- 查詢父子資訊:把一張表看成兩個一模一樣的表
select a.`categoryname`as '父欄目',b.`categoryname` as '子欄目'
from `category` as a, `category` as b
where a.`categoryid`=b.`pid`
分頁和排序
排序
-- 排序:升序 ASC,降序 DESC
-- ORDER BY 通過那個欄位排序,怎麼排
-- 查詢的結果根據, 成績降序 排序
SELECT s.`studentno`,`studentname`,`subjectname`,`studentresult`
FROM student s
INNER JOIN `result` r
ON s.studentno = r.studentno
INNER JOIN `subject` sub
ON r.`subjectno`=sub.`subjectno`
WHERE subjectname = '資料庫結構-1'
ORDER BY studentresult ASC
排序
-- 100萬
-- 為什麼要分頁?
-- 緩解資料庫壓力,給人的體驗更好, 瀑布流
-- 分頁,每頁只顯示五條資料
-- 語法:limit起始值,頁面大小
-- 網頁應用:當前,總頁數,頁面大小
-- limit 0,5 1~5
-- limit 1,5 2~6
-- limit 6,5
SELECT s.`studentno`,`studentname`,`subjectname`,`studentresu`
FROM student s
INNER JOIN `result` r
ON s.studentno = r.studentno
INNER JOIN `subject` sub
ON r.`subjectno` = sub.`subjectno`
WHERE subjectname = '資料庫結構-1'
ORDER BY studentresult ASC
LIMIT 5,5
-- 第一頁 limit 0,5 (1-1)*5
-- 第二頁 limit 5,5 (2-1)*5
-- 第三頁 limit 10,5 (3-1)*5
-- 第N頁 limit (n-1)*5,5 (n-1)*pagesize,pagesize
-- 【pagesize:頁面大小】
-- 【(n-1)*pagesieze:起始值】
-- 【n:當前頁】
-- 【資料總數/頁面大小 = 總頁數】
語法:limit(查詢起始下標,pagesize)
子查詢
where(這個值是計算出來的)
本質:在where語句中巢狀一個子查詢語句
-- 1、查詢 資料庫結構-1 的所有考試結果(學號,科目編號,成績),降序排列
-- 方式一: 使用連線查詢
select `studentno`,r.`subjectno`,`studentresult`
from `result` r
inner join `subject` sub
on r.subjectno = sub.subjectno
where subjectname= '資料庫結構-1'
order by studentresult desc
-- 方式二: 使用子查詢(由裡到外)
select `studentno`,`subjectno`,`studentresult`
from `result`
where `subjectno`=(
select `subjectno` from `subject`
where subjectname = '資料庫結構-1'
)
ORDER BY studentresult DESC
-- 查詢課程為 高等數學-2 且分數不小於80分的同學的學號和姓名
select s.`studentno`,`studentname`
from `student` s
inner join `result` r
on s.`studentno`=r.`studentno`
inner join `subject` sub
on r.`subjectno`=sub.`subjectno`
where `subjectname`='高等數學-2' and studentresult>=80
-- 分數不小於80份的學生的學號和姓名
select distinct s.`studentno`,`studentname`
from student s
inner join result r
on r.studentno = s.studentno
where studentresult>=80
-- 在這個基礎上增加一個科目 高等數學-2
-- 查詢高等數學2的編號
SELECT DISTINCT s.`studentno`,`studentname`
FROM student s
INNER JOIN result r
ON r.studentno = s.studentno
WHERE studentresult>=80 and subjectno=(
select subjectno from `subject`
where subjectname = '高等數學-2'
)
-- 在改造(由裡及外)
SELECT DISTINCT `studentno`,`studentname` from student where studentno in(
select studentno from result where studentresult>80 and subjectno={
SELECT subjectno FROM `subject` WHERE subjectname = '高等數學-2'
}
)
分組和過濾
-- 查詢不同課程的平均分,最高分,最低分,平均分大於80
-- 核心: (根據不同的課程分組)
SELECT `subjectname`,AVG(`studentresult`)AS 平均分,MAX(`studentresult`)AS 最高分,MIN(`studentresult`)AS 最低分
FROM result r
INNER JOIN `subject` sub
ON r.`subjectno`=sub.`subjectno`
GROUP BY r.`subjectno` -- 通過什麼欄位來分組
HAVING 平均分 > 80