第九章 MySQL中LIMIT和NOT IN案例
一.案例的項目
1.創建數據庫語句:
#創建數據庫
CREATE DATABASE `schoolDB`;
USE `schoolDB`;
#創建學生表
CREATE TABLE `student`(
`sid` INT(4) AUTO_INCREMENT NOT NULL PRIMARY KEY COMMENT'學生編號',
`stuName` VARCHAR(10) NOT NULL COMMENT'學生姓名',
`age` INT(4) NOT NULL COMMENT'年齡',
`sex` INT(1) NOT NULL COMMENT'學生性別'
)ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='學生信息表';
#創建課程表
CREATE TABLE `course`(
`cid` INT(4) PRIMARY KEY COMMENT'課程編號',
`cName` VARCHAR(50) NOT NULL COMMENT'課程名稱',
`tid` INT(4) NOT NULL COMMENT'教師編號'
)ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='課程信息表';
#創建成績表
CREATE TABLE `score`(
`sid` INT(4) COMMENT'學生編號',
`cid` INT(4) COMMENT'課程便號',
`score` INT(4) NOT NULL COMMENT'成績'
)ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='成績表';
#創建教師 表
CREATE TABLE `teacher`(
`tid` INT(4) PRIMARY KEY COMMENT'教師編號',
`teaName` VARCHAR(50) NOT NULL COMMENT'教師姓名'
)ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='教師信息表';
#創建`score表`主鍵
ALTER TABLE `score` ADD CONSTRAINT `pk_score` PRIMARY KEY `score`(`sid`,`cid`);
#創建課程表外鍵外鍵關聯 教師表 教師編號
ALTER TABLE `course` ADD CONSTRAINT `fk_course_teacher` FOREIGN KEY (`tid`) REFERENCES `teacher`(`tid`);
#創建成績表外鍵關聯 學生表 學生編號
ALTER TABLE `score` ADD CONSTRAINT `fk_score_student` FOREIGN KEY (`sid`) REFERENCES `student`(`sid`);
#創建成績表外鍵關聯 課程表 課程編號
ALTER TABLE `score` ADD CONSTRAINT `fk_score_course` FOREIGN KEY (`cid`) REFERENCES `course`(`cid`);
#插入學生表 數據
INSERT INTO `student` VALUES(1,'張三',16,1);
INSERT INTO `student` VALUES(2,'李三思',17,1);
INSERT INTO `student` VALUES(3,'李大齊',16,1);
INSERT INTO `student` VALUES(4,'王曉花',16,0);
INSERT INTO `student` VALUES(5,'劉得住',17,1);
INSERT INTO `student` VALUES(6,'謝謝你',16,1);
INSERT INTO `student` VALUES(7,'吳三桂',16,1);
INSERT INTO `student` VALUES(8,'桂花',16,0);
#插入教師表 數據
INSERT INTO `teacher` VALUES(101,'朱大胖');
INSERT INTO `teacher` VALUES(102,'方芳');
INSERT INTO `teacher` VALUES(103,'劉博士');
#插入課程表 數據
INSERT INTO `course` VALUES(1011,'語文',101);
INSERT INTO `course` VALUES(1012,'英語',102);
INSERT INTO `course` VALUES(1013,'數學',103);
#插入成績表 數據
INSERT INTO `score` VALUES(1,1011,90);
INSERT INTO `score` VALUES(1,1012,70);
INSERT INTO `score` VALUES(1,1013,60);
INSERT INTO `score` VALUES(2,1011,88);
INSERT INTO `score` VALUES(2,1012,70);
INSERT INTO `score` VALUES(2,1013,70);
INSERT INTO `score` VALUES(3,1011,92);
INSERT INTO `score` VALUES(3,1012,71);
INSERT INTO `score` VALUES(3,1013,65);
INSERT INTO `score` VALUES(4,1011,99);
INSERT INTO `score` VALUES(4,1012,78);
INSERT INTO `score` VALUES(4,1013,88);
INSERT INTO `score` VALUES(5,1011,87);
INSERT INTO `score` VALUES(5,1012,79);
INSERT INTO `score` VALUES(5,1013,62);
INSERT INTO `score` VALUES(6,1011,56);
INSERT INTO `score` VALUES(6,1012,65);
INSERT INTO `score` VALUES(6,1013,75);
INSERT INTO `score` VALUES(7,1011,50);
INSERT INTO `score` VALUES(7,1012,55);
INSERT INTO `score` VALUES(7,1013,51);
INSERT INTO `score` VALUES(8,1011,95);
INSERT INTO `score` VALUES(8,1012,59);
INSERT INTO `score` VALUES(8,1013,64);
2.執行SQL查詢
USE `schooldb`;
/*1.查詢學過“方芳”老師所教課程的學生的學號、姓名。(假定學生所學的課程均參加了考試)。*/
#測試通過
SELECT `sid`,`stuName` FROM `student` WHERE `sid` IN(
SELECT `sid` FROM `score` WHERE `cid`=(
SELECT `cid` FROM `course` WHERE `tid`=(
SELECT `tid` FROM `teacher` WHERE `teaName`='方芳'
)
)
);
3.NOT IN取反的經典應用
/*2.查詢所有課程成績均小於60分的學生學號和姓名。*/
#改一下數據才有符合要求的數據
UPDATE `score` SET `score`=50 WHERE `sid`=7 AND `cid`=1013;
SELECT `sid`,`stuName` FROM `student` WHERE `sid` NOT IN(
SELECT `sid` FROM `score`
WHERE `score`>60
);
/*難點:步驟分析:
1.查詢所有分數大於60的學生編號
2.取反,不在所有大於60分的里面的學生,就是所有成績小於60的學生
*/
4.LIMIT不支持子查詢的解決方法
/*3.查詢“方芳”老師所教的“數據庫”課程成績排名在第3~6名的學生學號、姓名,
並將此記錄插入新表tempScore中。(要求使用limit子句)*/
CREATE TABLE `tempScore`(
SELECT `sid`,`stuName` FROM `student` WHERE `sid` IN(
#查詢方芳老師所教課程第3-6名學員的編號
SELECT `sid` FROM(
SELECT `sid` FROM `score` WHERE `cid` IN(
SELECT `cid` FROM `course` WHERE `tid`=(
SELECT `tid` FROM `teacher` WHERE `teaName`='方芳'
)
)GROUP BY `score` DESC LIMIT 2,4
)AS ta
)
);
/*難點:問題出現在mysql不支持在子查詢中使用limit報錯:This version of MySQL doesn’t yet support ‘LIMIT & IN/ALL/ANY/SOME subquery
解決的方法是:在limit子句外面加上一層查詢"SELECT `sid` FROM()
並且給from的結果集取上別名,就不會報錯
*/
4.HAVING進行分組的應用
/*4.查詢有兩門以上課程不及格的學生學號及其平均成績。*/
SELECT s.sid, AVG(sc.score)
FROM `student` AS s, `score` AS sc
WHERE s.sid IN
(
SELECT `sid` FROM `score`
WHERE `score` < 60
GROUP BY `sid`
HAVING COUNT(`cid`)>= 2
)
AND s.sid=sc.sid
GROUP BY s.sid
/*用到了having 分組*/
5.創建視圖
/*5.創建視圖student_view,用於查詢所有學生的學號、姓名、參加考試課程數、各科總成績。*/
CREATE VIEW `student_view`
AS
SELECT s.sid,s.stuName,COUNT(c.cid),SUM(sc.score) FROM `student`AS s
INNER JOIN `score` AS sc ON sc.sid=s.sid
INNER JOIN `course` AS c ON c.cid = sc.cid
GROUP BY s.sid;