SQL——基礎語句練習

主要是針對,一些經常遇到的SQL語句,進行了初步的總結。可以檢驗對sql的學習程度,對SQL語句進行進一步鞏固以及加強。

準備工作

  • 首先需要創建四個表,分別是:student(學生表),teacher(教師表),score(成績表),course(課程表)
  • 建表SQL以及初始數據預置
    • student:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `stuNo` int(10) NOT NULL,
  `stuName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `stuSex` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `stuAge` int(255) DEFAULT NULL,
  PRIMARY KEY (`stuNo`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '張一', '男', 15);
INSERT INTO `student` VALUES (2, '張二', '女', 35);
INSERT INTO `student` VALUES (3, '張三', '女', 27);
INSERT INTO `student` VALUES (4, '張四', '男', 15);

SET FOREIGN_KEY_CHECKS = 1;
    • teacher:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher`  (
  `teaNo` int(11) NOT NULL,
  `teaName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  PRIMARY KEY (`teaNo`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of teacher
-- ----------------------------
INSERT INTO `teacher` VALUES (1, '孫一');
INSERT INTO `teacher` VALUES (2, '孫二');

SET FOREIGN_KEY_CHECKS = 1;
    • score:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for score
-- ----------------------------
DROP TABLE IF EXISTS `score`;
CREATE TABLE `score`  (
  `id` int(11) NOT NULL,
  `stuNo` int(11) DEFAULT NULL,
  `cNo` int(11) DEFAULT NULL,
  `score` int(255) DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of score
-- ----------------------------
INSERT INTO `score` VALUES (1, 1, 1, 60);
INSERT INTO `score` VALUES (2, 1, 2, 25);
INSERT INTO `score` VALUES (3, 1, 3, 56);
INSERT INTO `score` VALUES (4, 1, 4, 100);
INSERT INTO `score` VALUES (5, 1, 5, 63);
INSERT INTO `score` VALUES (6, 2, 1, 5);
INSERT INTO `score` VALUES (7, 2, 2, 29);
INSERT INTO `score` VALUES (8, 2, 3, 59);
INSERT INTO `score` VALUES (9, 2, 4, 60);
INSERT INTO `score` VALUES (10, 2, 5, 65);
INSERT INTO `score` VALUES (11, 3, 1, 60);
INSERT INTO `score` VALUES (12, 3, 2, 100);
INSERT INTO `score` VALUES (13, 3, 3, 88);
INSERT INTO `score` VALUES (14, 3, 4, 75);
INSERT INTO `score` VALUES (15, 3, 5, 65);
INSERT INTO `score` VALUES (16, 4, 1, 60);
INSERT INTO `score` VALUES (17, 4, 2, 57);
INSERT INTO `score` VALUES (18, 4, 3, 86);
INSERT INTO `score` VALUES (19, 4, 4, 73);
INSERT INTO `score` VALUES (20, 4, 5, 62);

SET FOREIGN_KEY_CHECKS = 1;
    • course:
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course`  (
  `cNo` int(11) NOT NULL,
  `cName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  `cTeacher` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL,
  PRIMARY KEY (`cNo`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES (1, '數學', '1');
INSERT INTO `course` VALUES (2, '語文', '1');
INSERT INTO `course` VALUES (3, '英語', '2');
INSERT INTO `course` VALUES (4, '美術', '2');
INSERT INTO `course` VALUES (5, '音樂', '2');

SET FOREIGN_KEY_CHECKS = 1;

表說明

針對上面所創建的四個表的屬性進行說明。

  • Student學生表:主要四個屬性 StuNo(主鍵)學生的學號,stuName 學生的姓名,stuSex 學生的性別,stuAge 學生的年紀
    img
  • teacher老師表:主要就兩個屬性:teaNo(主鍵)老師的工號,teaName 老師的姓名
    img
  • score成績表:主要就四個屬性:id(主鍵),stuNo(與學生表關聯)學生的學號,cNo(與課程表關聯)課程號,score 成績
    img
  • course 課程表:cNo(主鍵)課程號,cName課程名稱,cTeacher(和教師表關聯)教師工號
    img

經典SQL語句練習

建議大家還是先自己嘗試解決,遇到困難再去看解析和具體的代碼,要是有更好的想法或者不同的意見歡迎大家在評論區進行討論

  • 查詢“1”課程比“2”課程成績高的所有學生的學號
select a.stuNo from score a,score b where a.cNo='1'and b.cNo='2' and  a.stuNo=b.stuNo and a.score>b.score;

這個比較簡單,主要就是從兩個表裏讀取數據,通過學號相等來進行查找。

  • 查詢平均成績大於60分的同學的學號和平均成績
select stuNo,AVG(score) from score group by stuNo  having avg(score)>60  ;

首先使用AVG這個函數來取平均值,然後使用group by進行分組

  • 查詢所有同學的學號、姓名、選課數、總成績
select a.stuNo,a.stuName,count(cNo),sum(score) from student a,score b  where a.stuNo=b.stuNo  group by a.stuNo,a.stuName  ;

和上面那個差不多,主要使用count進計數和sum進行求和

  • 查詢姓“孫”的老師的個數
SELECT count(teaName) ,'孫'as 'Name'from teacher WHERE teaName like '孫%'

主要使用like相似查詢,並且使用%進行適配,以及使用as來顯示

  • 查詢沒學過“孫一”老師課的同學的學號、姓名
select stuNo,stuName from student where stuNo not in (SELECT a.stuNo from student a,score b WHERE a.stuNo=b.stuNo and cNo in(SELECT d.cNo from teacher c,course d WHERE c.teaNo=d.cTeacher and c.teaName='孫一'))

​ 主要分爲三個步驟:首先先查詢孫一老師教什麼課,然後再使用in查詢什麼學生上過這些課,然後使用not in查詢沒有包含在這些裏面的學生。

  • 查詢學過“1”並且也學過編號“2”課程的同學的學號、姓名
SELECT a.stuNo,a.stuName from student a, score b,score c WHERE a.stuNo=b.stuNo and b.stuNo=c.stuNo and b.cNo='1'and c.cNo='2'

這個相對簡單,只是涉及到三個表,注意每個表之間的聯繫就可以

  • 查詢課程編號“2”的成績比課程編號“1”課程低的所有同學的學號、姓名
方法一:
SELECT a.stuNo,a.stuName from student a,score b ,score c WHERE a.stuNo=b.stuNo and a.stuNo=c.stuNo and b.cNo='2'and c.cNo='1'and b.score > c.score;
方法二:
select stuNo,stuName from student  where stuNo in   (select a.stuNo from score a,score b  where a.cNo='1' and b.cNo='2' and a.stuNo=b.stuNo and a.score>b.score)

第一個方法和上一個差不多。就是多了進行成績的比較

第二個方法就是換了個寫法來進行操作

  • 查詢沒有學全所有課的同學的學號、姓名
SELECT a.stuNO,a.stuName FROM student a, score b,course c WHERE a.stuNo=b.stuNo  group by b.stuNo,a.stuName  having count(b.cNo)<(select count(cNo) from course)

就是學生選的課的總數和課程總數進行比較,

  • 查詢至少有一門課與學號爲“1”的同學所學相同的同學的學號和姓名
select distinct a.stuNo,stuName from student a,score b  where a.stuNo=b.stuNo and cNo in (select cNo from score   where stuNo='001')

先把學號一的學生選的課找出來,然後進行查找

  • 查詢各科成績最高和最低的分:以如下形式顯示:課程ID,最高分,最低分
select  cNo,max(score) as 最高分,min(score) as 最低分 from score  group by cNo

  • 刪除“2”同學的“1”課程的成績
delete from score where stuNo='2' and cNo='1'

  • 查詢和" 01 "號的同學學習的課程完全相同的其他同學的信息
SELECT * from student WHERE stuNo in (SELECT  stuNo FROM score WHERE cNo in(SELECT distinct cNo FROM score WHERE stuNo='01')and stuNo<>'01'GROUP BY stuNo having count(cNo)>=4);

  • 查詢兩門及其以上不及格課程的同學的學號,姓名及其平均成績
select a.stuNo,a.stuName,b.平均成績 FROM student a right join (select stuNo,AVG(score)平均成績 from score where score<60 group by stuNo having COUNT(score)>=2)b on a.stuNo=b.stuNo;

  • 查詢各科成績最高分、最低分和平均分:以如下形式顯示:課程 ID ,課程 name ,最高分,最低分,平均分,及格率,中等率,優良率,優秀率及格爲>=60,中等爲:70-80,優良爲:80-90,優秀爲:>=90
select distinct A.cNo,cName,最高分,最低分,平均分,及格率,中等率,優良率,優秀率 from score A
left join Course on A.cNo=course.cNo
left join (select cNo,MAX(score)最高分,MIN(score)最低分,AVG(score)平均分 from score group by cNo)B on A.cNo=B.cNo
left join (select cNo,(((sum(case when score>=60 then 1 else 0 end)*1.00)/COUNT(*))*100)及格率 from score group by cNo)C on A.cNo=C.cNo
left join (select cNo,(((sum(case when score >=70 and score<80 then 1 else 0 end)*1.00)/COUNT(*))*100)中等率 from score group by cNo)D on A.cNo=D.cNo
left join (select cNo,(((sum(case when score >=80 and score<90 then 1 else 0 end)*1.00)/COUNT(*))*100)優良率 from score group by cNo)E on A.cNo=E.cNo
left join (select cNo,(((sum(case when score >=90 then 1 else 0 end)*1.00)/COUNT(*))*100)優秀率 
from score group by cNo)F on A.cNo=F.cNo
  • .按各科成績進行排序,並顯示排名,Score 重複時保留名次空缺(不保留)
保留
select *,RANK()over(order by score desc)排名 from score;
不保留
select *,DENSE_RANK()over(order by score desc)排名 from score
  • 查詢學生的總成績,並進行排名,總分重複時保留名次空缺
select *,RANK()over(order by 總成績 desc)排名 from(
select stuNo,SUM(score)總成績 from score group by stuNo)A
  • 查詢各科成績前三名的記錄
select * from(select *,rank()over (partition by stuNo order by score desc)A from score)B where B.A<=3
select * from score a where (select COUNT(*) from score where cNo=a.cNo and score>a.score)<3 order by a.cNo,a.score desc

如何提高SQL查找效率

  • select子句中儘量避免使用*
    • 另外select * 用於奪標聯結,會造成更大的成本開銷
  • where子句比較符號左側避免函數,移到右邊
  • 儘量避免使用in和not in
  • 儘量避免使用ro,用union來代替
  • 用limit子句限制返回的數據行數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章