1. 程式人生 > 其它 >DQL查詢資料

DQL查詢資料

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

select小結