面向考試數據庫—單表查詢(包含建表數據)

在這裏插入圖片描述
面向考試數據庫系列博客以筆者的思維腦圖爲主線,博文內容爲筆者對導圖的具體分支所作的詳細闡述,其中不足,望讀者多加指正。

引言

  學習了一段時間SQL語言之後,其中操作了解到了很多,筆者按照上述腦圖進行現階段的SQL學習,到此在單表查詢處涉及到了許多的SQL語句操作,故做此文作爲筆記總結之用,其中也插入31到SQL查詢例題進行求解闡述,希望幫助讀者對知識進行更好的消化。主要內容如下:
在這裏插入圖片描述

● 建立練習數據庫(之後習題亦是基於該庫)

  開始正文前,讀者需要先了解博客使用的庫表結構;該庫爲一個選課庫,主要庫內容如下圖所示:
在這裏插入圖片描述

建表源碼

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course`  (
  `Cno` char(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `Cname` char(40) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `Cpno` char(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `Ccredit` smallint(6) NULL DEFAULT NULL,
  PRIMARY KEY (`Cno`) USING BTREE,
  INDEX `Cpno`(`Cpno`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES ('1', '數據庫', '5', 4);
INSERT INTO `course` VALUES ('2', '數學', NULL, 2);
INSERT INTO `course` VALUES ('3', '信息系統', '1', 4);
INSERT INTO `course` VALUES ('4', '操作系統', '6', 3);
INSERT INTO `course` VALUES ('5', '數據結構', '7', 4);
INSERT INTO `course` VALUES ('6', '數據處理', NULL, 2);
INSERT INTO `course` VALUES ('7', 'PASCAL語言\r', '6', 4);

-- ----------------------------
-- Table structure for sc
-- ----------------------------
DROP TABLE IF EXISTS `sc`;
CREATE TABLE `sc`  (
  `Sno` char(9) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '學號',
  `Cno` char(4) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '課程號',
  `Grade` smallint(255) NULL DEFAULT NULL COMMENT '成績\r\n',
  PRIMARY KEY (`Sno`, `Cno`) USING BTREE,
  CONSTRAINT `Sno` FOREIGN KEY (`Sno`) REFERENCES `student` (`Sno`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of sc
-- ----------------------------
INSERT INTO `sc` VALUES ('200215121', '1', 92);
INSERT INTO `sc` VALUES ('200215121', '2', 85);
INSERT INTO `sc` VALUES ('200215121', '3', 88);
INSERT INTO `sc` VALUES ('200215122', '2', 90);
INSERT INTO `sc` VALUES ('200215122', '3', 80);

-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student`  (
  `Sno` char(9) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `Sname` char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `Ssex` char(2) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `Sage` smallint(6) NULL DEFAULT NULL,
  `Sdept` char(20) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`Sno`) USING BTREE,
  UNIQUE INDEX `Sname`(`Sname`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('200215121', '李勇', '男', 20, 'CS');
INSERT INTO `student` VALUES ('200215122', '劉晨', '女', 19, 'CS');
INSERT INTO `student` VALUES ('200215123', '王敏', '女', 18, 'MA');

SET FOREIGN_KEY_CHECKS = 1;

單表查詢知識點彙總

 關於單表查詢的主要操作,主要可以分爲5類“題型”。想要熟練的掌握解決好這幾類題型,基礎知識必需要紮實,關於單表的基礎知識,筆者總結如下了內容。
 首先是常用的查詢條件;
在這裏插入圖片描述
 其次要注意的是一些細節性的知識點;

  1. 關於排序 ;
    可以按一個或多個屬性列排序
    .升序:ASC;降序:DESC;缺省值爲升序
    當排序列含空值時
    .ASC:排序列爲空值的元組最後顯示
    .DESC:排序列爲空值的元組最先顯示

  2. 關於計數;
    COUNT([DISTINCT|ALL] *)
    COUNT([DISTINCT|ALL] <列名>)
    計算總和
    SUM([DISTINCT|ALL] <列名>)
    計算平均值
    AVG([DISTINCT|ALL] <列名>)
    最大最小值
    MAX([DISTINCT|ALL] <列名>)
    MIN([DISTINCT|ALL] <列名>)
    DISTINCT短語:在計算時要取消指定列中的重複值
    ALL短語:不取消重複值
    ALL爲缺省值

  3. 關於分組;
    group by 細化聚集函數的作用對象 未對查詢結果分組,聚集函數將作用於整個查詢結果
    對查詢結果分組後,聚集函數將分別作用於每個組 按指定的一列或多列值分組,值相等的爲一組 HAVING短語與WHERE子句的區別;
    作用對象不同 WHERE子句作用於基表或視圖,從中選擇滿足條件的元組 HAVING短語作用於組,從中選擇滿足條件的組。

  4. 關於通配符匹配問題;
    通配符匹配(% (百分號) 代表任意長度(長度可以爲0)的字符串;_ (下橫線) 代表任意單個字符);
    使用換碼字符將通配符轉義爲普通字符( ESCAPE ‘\’ 表示“ \” 爲換碼字符 )這裏筆者使用的查詢工具不需要使用到ESCAPE ,用到\即可;
    涉及空值的查詢( “IS” 不能用 “=” 代替)。

  5. 關於多重條件查詢;
    多重條件查詢(AND的優先級高於OR;可以用括號改變優先級;可用來實現多種其他謂詞)。

單表查詢練習題32道

有了這些知識,我們就可以去嘗試上手解決關於單表查詢的32到例題了,關於例題的,筆者先給出腦圖分佈。
在這裏插入圖片描述

(1)選取表中的若干列

#例子1:查詢全體學生的學號與姓名。
SELECT Sno,Sname FROM Student;

#例子2:查詢全體學生的姓名、學號、所在系。
SELECT Sname,Sno,Sdept FROM student;

#[例3]  查詢全體學生的詳細記錄。
SELECT  * FROM Student;

#[例4]  查全體學生的姓名及其出生年份。
SELECT Sname,2004-Sage AS BIRTH    /*假定當年的年份爲2004年*/ FROM Student;

[5]  查詢全體學生的姓名、出生年份和所有系,要求用小寫字母表示所有系名
SELECT Sname,2004-Sage AS 'year of Brith',LOWER(Sdept) FROM student;

使用列別名改變查詢結果的列標題:
SELECT Sname NAME ,'year of Brith:' BRITH,2004-Sage Brithday ,LOWER(Sdept) Department FROM student;

(2)選擇表中若干元祖

 這類題型在單表查詢中設計的知識點最多,也是最需要注意的。

#普通選取
[6]  查詢選修了課程的學生學號。(取消重複行)
SELECT DISTINCT Sno FROM sc;

查詢選修課程的各種成績
 SELECT DISTINCT Cno,Grade FROM SC; 
 
 #大小比較
 [例7]  查詢計算機科學系全體學生的名單。
 SELECT Sname
    FROM Student
    WHERE Sdept='CS';
		
	[8]  查詢所有年齡在20歲以下的學生姓名及其年齡。
	SELECT Sname,Sage 
FROM    Student    
WHERE Sage < 20;

[例9]  查詢考試成績有不及格的學生的學號。
 SELECT DISTINCT Sno
    FROM  SC
    WHERE Grade<60;
		
#範圍選取
[10] 查詢年齡在20~23歲(包括20歲和23歲)之間的學生的姓名、系別和年齡
 SELECT Sname,Sdept,Sage
FROM     Student
WHERE   Sage BETWEEN 20 AND 23;

[11]  查詢年齡不在20~23歲之間的學生姓名、系別和年齡
SELECT Sname,Sdept,Sage
FROM     Student
WHERE   Sage NOT BETWEEN 20 AND 23;

#集合確定
[12]查詢信息系(IS)、數學系(MA)和計算機科學系(CS)學生的姓名和性別。
SELECT Sname,Ssex
	FROM  Student
	WHERE Sdept IN ( 'IS','MA','CS' );
	
[13]查詢既不是信息系、數學系,也不是計算機科學系的學生的姓名和性別
SELECT Sname,Ssex
	FROM  Student
	WHERE Sdept NOT IN ( 'IS','MA','CS' );
	
#字符匹配
匹配串爲固定字符串
[14]  查詢學號爲200215121的學生的詳細情況。
SELECT *    
     FROM  Student  
     WHERE  Sno LIKE '200215121';
 [15]  查詢所有姓劉學生的姓名、學號和性別
 SELECT Sname ,Sno,Ssex 
 FROM student
 WHERE Sname LIKE '劉%';
 
 [16]  查詢姓"歐陽"且全名爲三個漢字的學生的姓名。
 SELECT Sname 
 FROM student 
 WHERE Sname like '歐陽_';
 
 [17]  查詢名字中第2個字爲"陽"字的學生的姓名和學號。
 SELECT Sname,Sno
      FROM Student
      WHERE Sname LIKE '__陽%';
			
[18]  查詢所有不姓劉的學生姓名。
SELECT Sname,Sno,Ssex
      FROM Student
      WHERE Sname NOT LIKE '劉%';
			
#3) 使用換碼字符將通配符轉義爲普通字符( ESCAPE '\' 表示“ \” 爲換碼字符 )
 [19]  查詢DB_Design課程的課程號和學分。
SELECT Cno,Ccredit
FROM Course
WHERE Cname LIKE'DB\_Design';

# [例20]  查詢以"DB_"開頭,且倒數第3個字符爲 i的課程的詳細情況。
SELECT * FROM Course
WHERE Cname LIKE 'DB\_%i_ _' ;

#關於空值的查詢
 [21某些學生選修課程後沒有參加考試,所以有選課記錄,但沒有考試成績。查詢缺少成績的學生的學號和相應的課程號。
 SELECT Sno,Cno
      FROM  SC
      WHERE  Grade IS NULL;
			
[22]  查所有有成績的學生學號和課程號。
SELECT Sno,Cno
      FROM  SC
      WHERE  Grade IS NOT NULL;
			
[23]  查詢計算機系年齡在20歲以下的學生姓名。
SELECT Sname
       FROM  Student
       WHERE Sdept= 'CS' AND Sage<20;

[12]  查詢信息系(IS)、數學系(MA)和計算機科學系(CS)學生的姓名和性別。(變)
SELECT Sname,Ssex
FROM   Student
WHERE  Sdept= ' IS ' OR Sdept= ' MA' OR Sdept= ' CS ';

[10]  查詢年齡在20~23歲(包括20歲和23歲)之間的學生的姓名、系別和年齡。(變)
SELECT Sname,Sdept,Sage
FROM Student
     WHERE  Sage>=20 AND Sage<=23;

(3)order by 子句

 這類題型對於解決排名問題有很有幫助的。

#ORDER BY子句
[24]  查詢選修了3號課程的學生的學號及其成績,查詢結果按分數降序排列。
SELECT Sno,Grade
        FROM  SC
        WHERE  Cno= ' 3 '
        ORDER BY Grade DESC;
				
[例25]  查詢全體學生情況,查詢結果按所在系的系號升序排列,同一系中的學生按年齡降序排列。
SELECT  *
        FROM  Student
        ORDER BY Sdept,Sage DESC;

(4)聚集函數

 筆者認爲有一定的統計作用。

 [26]  查詢學生總人數。
	SELECT COUNT(*)
    FROM  Student;
		
	[27]  查詢選修了課程的學生人數。
	SELECT COUNT(DISTINCT Sno)
     FROM SC;
		 
  [28]  計算1號課程的學生平均成績。
	SELECT AVG(Grade)
          FROM SC
          WHERE Cno= ' 1 ';
					
	   [29]  查詢選修1號課程的學生最高分數。
	 SELECT MAX(Grade)
   FROM SC
   WHERE Cno= ' 1 ';
	 

(5)Group by 子句

 SQL查詢將Group by子句與聚集函數綜合利用可進一步解決更多地問題。

[31]  求各個課程號及相應的選課人數。
 SELECT Cno,COUNT(Sno)
     FROM    SC
     GROUP BY Cno;32] 查詢選修了3門以上課程的學生學號
 SELECT Sno
     FROM  SC
     GROUP BY Sno
     HAVING  COUNT(*) >3;

小結

 對於用慣了python的筆者而言,覺得MySQL的語言編輯還是比較友好的,比如代碼自動補全、大小寫友好、不用考慮python需要考慮的排版問題。另外筆者使用的使用的爲Navicat 12 for MySQL企業版本的查詢環境。不同版本在個別例題的實現上可能會有細微的不同,需要讀者自己注意。文章不足之處望多加指針。

一段

 話說一貴婦最近老是犯偏頭疼的毛病,找了許多醫生診治,都未能見效,這天,朋友介紹她去找一位著名的醫生,據說其專治各種疑難雜症。貴婦抱着試一試的態度,來到這位醫生的診所診治,說完自己的病況,醫生說:“害!小病嘛,我按着我的法子來,當天就見效,你只要每天早晨起牀雙手按着自己的太陽穴時對着鏡子說:“我不會頭疼,我不會頭疼, 堅持一段時間後,就好的。”說完後,就讓貴婦回家。一些日子後,貴婦和她丈夫送來一面錦旗向醫生道謝,貴婦:“醫生醫術高超,實在感謝您,特送錦旗向您道謝。”醫生:“害!應該的應該的嘛。“貴婦偷偷想醫生道:”醫生啊,您能幫看看我老公的毛病嘛?’他最近一段日子總是不舉“醫生:”簡單,不過您要先出去避讓一下纔好,我好和您丈夫道明解決之道啊。“貴婦:”害!理解理解,我這就出去您慢慢和我老公說。事成之後我必重謝!“
 你還別說,貴婦丈夫經過那名神醫診治後啊,沒過多久就恢復了往日的雄風,而且是有過之而不及啊。於是貴婦準備一份大禮贈送與那名神醫。不過,貴婦發現,在睡前,老公總是偷偷在鏡子面前出雙手按着太陽穴說些什麼話。 一日,貴婦好奇心上頭,便去偷看監聽:只見貴婦老公雙手按着太陽穴對着鏡子說,她不是我老婆,她不是我老婆。 ……

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章