1. 程式人生 > >2017年07月03號課堂筆記

2017年07月03號課堂筆記

2017年 height des 出現 課堂 int 統計 顯示 value

2017年07月03號 星期一 多雲 空氣質量:輕度汙染~中度汙染

內容:MySQL第四節課

in和not in;兩個表的內連接;exists和not exsits的使用;all,any和some;

使用子查詢的註意事項;sql優化(使用exists 代替 in);group by;兩道mysql面試題

一、in和not in

1、in
-- 使用in替換 等於(=)的子查詢語句!
-- in後面的子查詢可以返回多條記錄!

1)例題1
-- 查詢年級編號是1或者2 的 所有學生列表

SELECT * FROM student WHERE gradeId IN(1,2)
2)例題2
-- 查詢 年級名稱是 大一或者大二的所有學生信息

-- 分析:學生表中沒有 年級名稱 但是有年級編號

-- 01.根據 年級名稱 查詢出 年級編號
SELECT gradeID FROM grade WHERE gradeName IN(‘大一‘,‘大二‘);

-- 02.再根據 年級編號 查詢學生信息
SELECT * FROM student WHERE
gradeID
IN (SELECT gradeID FROM grade WHERE gradeName IN(‘大一‘,‘大二‘))

3)例題3(使用where ... =)
-- 查詢參加最近一次 高等數學-1 考試的學生 成績的最高分和最低分

-- 01. 發現成績表中 沒有 編號 只有科目名稱!根據名稱取編號

SELECT SubjectNo FROM `subject` WHERE
subjectName=‘高等數學-1‘

-- 02.查詢最近一次 高等數學-1 考試的時間

SELECT MAX(ExamDate) FROM result
WHERE
SubjectNo=(SELECT SubjectNo FROM `subject` WHERE
subjectName=‘高等數學-1‘)

-- 02(2).所有最近考試的成績(老師上課演示用,可以不寫)
SELECT * FROM result
WHERE ExamDate=‘2013-11-11 16:00:00‘

-- 03.開始獲取最高分和 最低分
SELECT MAX(studentResult) AS 最高分,
MIN(studentResult) AS 最低分
FROM result
WHERE SubjectNo=

(SELECT SubjectNo FROM `subject` WHERE
subjectName=‘高等數學-1‘)
AND ExamDate=
(SELECT MAX(ExamDate) FROM result
WHERE
SubjectNo=(SELECT SubjectNo FROM `subject` WHERE
subjectName=‘高等數學-1‘))

4)例題4(使用where ... in)
-- 查詢 高等數學-1 考試成績是 60 分的 學生信息

-- 01.根據 科目名稱 獲取 科目編號
SELECT SubjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘

-- 02.根據科目編號 和 考試成績條件 查詢所有的學生編號
SELECT studentNo FROM result
WHERE SubjectNo=(SELECT SubjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘)
AND StudentResult=60; -- 成績=60

-- 03.根據符合條件學生編號 查詢對應的學生信息
SELECT * FROM student
WHERE studentNo IN
(SELECT studentNo FROM result
WHERE SubjectNo=(SELECT SubjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘)
AND StudentResult=60)


2、not in
-- not in :不在某個範圍之內

1)例題1
-- 查詢未參加 “高等數學-1” 課程最近一次考試的在讀學生名單

-- 01.根據 科目名稱 獲取 科目編號
SELECT SubjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘

-- 02根據科目編號 獲取該科目最近一次考試時間
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=
(SELECT SubjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘)

-- 03.查詢沒參加該科目 最近一次考試的 學生編號,學生姓名
SELECT studentNo,StudentName FROM student
WHERE studentNo NOT IN
(
SELECT StudentNo FROM result
WHERE SubjectNo=
(SELECT SubjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘)
AND ExamDate=
(SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=
(SELECT SubjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘))
)

二、高級查詢

1、笛卡爾乘積

1)概念:笛卡爾乘積是指在數學中,兩個集合XY的笛卡尓積(Cartesian product),又稱直積,表示為X × Y, 第一個對象是X的成員而第二個對象是Y的所有可能有序對的其中一個成員。 假設集合A={a, b},集合B={0, 1, 2}, 則兩個集合的笛卡爾積為{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。 類似的例子有,如果A表示某學校學生的集合,B表示該學校所有課程的集合,則A與B的笛卡爾積表示所有可能的選課情況。 A表示所有聲母的集合,B表示所有韻母的集合,那麽A和B的笛卡爾積就為所有可能的漢字全拼。

2)老師mysql舉例: SELECT * FROM `grade`INNER JOIN `student`
笛卡爾積 :兩個表數據的乘積!

2、兩個表的內連接
SELECT * FROM `grade`INNER JOIN `student`
ON grade.`GradeID`=student.`GradeId`

on 兩個表通過那一列建立關聯關系

3、exists的使用

1)語法和作用

-- 01. 用於檢測表,數據庫等等 是否存在

-- 02.檢查子查詢中是否會返回一行數據!其實子查詢並不返回任何數據!
只返回 true或者false!

SELECT * FROM Student WHERE EXISTS(SELECT NULL)
SELECT * FROM Student WHERE EXISTS(SELECT 9*9)
SELECT * FROM Student WHERE EXISTS(SELECT StudentName FROM student)

圖示如下:

技術分享

2)exists例題1  exists和in的轉換寫法

-- 01.exists的寫法

SELECT * FROM Student

WHERE EXISTS(SELECT studentName FROM Student WHERE studentName=‘張三‘)

-- 02.in的寫法

SELECT * FROM Student WHERE studentName IN(SELECT studentName FROM Student)

-- 03.in 效果等同於 =any
SELECT * FROM Student WHERE
studentName =ANY(SELECT studentName FROM Student)

3)all,any和some
-- 01.all 大於子查詢語句中的 最大值 >(1,2,3) >3
SELECT * FROM student
WHERE studentNo>ALL
(SELECT studentNo FROM student WHERE studentNo IN(1003,1004,1005))

-- 02.any 大於子查詢語句中的 最小值 >(1,2,3) >1
SELECT * FROM student
WHERE studentNo>ANY
(SELECT studentNo FROM student WHERE studentNo IN(1003,1004,1005))

-- 03.some 和any功能一樣
SELECT * FROM student
WHERE studentNo>SOME
(SELECT studentNo FROM student WHERE studentNo IN(1003,1004,1005))

4)exists例題2
-- 檢查“高等數學-1” 課程最近一次考試成績
-- 如果有 80分以上的成績,顯示分數排在前5名的學員學號和分數


-- ① 不使用exists

-- 01.查詢“高等數學-1” 課程 對應的編號
SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘

-- 02.查詢最近的考試成績
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘)

-- 03. 在02的基礎上 加條件 成績大於80
SELECT * FROM result
WHERE ExamDate=
(SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘))
AND StudentResult>80

-- 04.顯示分數排在前5名的學員學號和分數
SELECT studentNo,StudentResult FROM result
WHERE ExamDate=
(SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘))
AND StudentResult>80
ORDER BY StudentResult DESC
LIMIT 0,5

同樣題目:

-- 檢查“高等數學-1” 課程最近一次考試成績
-- 如果有 80分以上的成績,顯示分數排在前5名的學員學號和分數

-- ② 使用exists

-- 01.查詢“高等數學-1” 課程 對應的編號
SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘

-- 02.查詢最近的考試時間
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘)


-- 03.查詢學號和成績
SELECT StudentNo,StudentResult FROM result
WHERE EXISTS
(
SELECT * FROM result
WHERE subjectNo=(
SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘
)
AND ExamDate=(
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘)
)
AND StudentResult>80
)
AND subjectNo=(
SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘
)
AND ExamDate=(
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘)
)
ORDER BY StudentResult DESC
LIMIT 0,5

5)exists例題3
-- 如果有 年級名稱是大二 的學生,就 查詢出 年級名稱是大一的 所有學生信息

-- 01.先查詢出 對應的年級編號
SELECT GradeId FROM grade WHERE GradeName=‘大一‘
SELECT GradeId FROM grade WHERE GradeName=‘大二‘

-- 02.在學生表中是否存在 年級名稱是大二 的學生
SELECT * FROM student WHERE gradeID=(
SELECT GradeId FROM grade WHERE GradeName=‘大二‘
)

-- 03.如果有查詢出 年級名稱是大一的 所有學生信息
SELECT * FROM student
WHERE EXISTS
(
SELECT * FROM student WHERE gradeID=(
SELECT GradeId FROM grade WHERE GradeName=‘大二‘
)
)
AND GradeId=(
SELECT GradeId FROM grade WHERE GradeName=‘大一‘
)

6)not exists
例題如下:
-- 檢查“高等數學-1”課程最近一次考試成績
-- 如果全部未通過考試(60分及格),認為本次考試偏難,計算的該次考試平均分加5分

-- 01.查詢“高等數學-1” 課程 對應的編號
SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘

-- 02.查詢最近的考試成績
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘)

-- 03.查詢成績大於60的 (逆向思維)
SELECT StudentResult FROM result
WHERE StudentResult>60
AND SubjectNo=(
SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘
)
AND ExamDate=(
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘)
)

-- 04. 如果全部未通過考試,考試平均分加5分
SELECT AVG(StudentResult)+5 FROM result
WHERE NOT EXISTS
(
SELECT StudentResult FROM result
WHERE StudentResult>60
AND SubjectNo=(
SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘
)
AND ExamDate=(
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘)
)
)
AND SubjectNo=(
SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘
)
AND ExamDate=(
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName=‘高等數學-1‘)
)

7) 使用子查詢的註意事項
-- 01.任何允許使用表達式的地方都可以使用子查詢
-- 02.只出現在子查詢中但是沒有在父查詢中出現的列,結果集中的列不能包含

4、sql優化(使用exists 代替 in)

1)使用exists 代替 in
使用not exists 代替not in

exists 只返回true或者false.不返回結果集
in 返回結果集

-->exists性能更高!

2)例題1
-- 查詢姓李的學生信息 % 代表0或者多個字符 _代表一個字符

-- 01.使用like
SELECT * FROM student WHERE StudentName LIKE ‘李%‘
SELECT * FROM student WHERE StudentName LIKE ‘李_‘

-- 02.使用in完成上述代碼
SELECT * FROM student WHERE StudentName IN(
SELECT studentName FROM student WHERE StudentName LIKE ‘李%‘)
-- in(多條數據--》返回結果集)

-- 03.使用exists替換
SELECT * FROM student WHERE EXISTS(
SELECT studentName FROM student)
AND StudentName LIKE ‘李%‘
-- exists(有沒有數據)

5. GROUP BY 列名 分組   having 分組之後的條件
1)例題1
-- 統計每門課程平均分各是多少
SELECT subjectno,AVG(studentresult) FROM result
GROUP BY subjectno

2)例題2
-- 查詢出課程平均分大於60的課程編號 和 平均分
SELECT subjectno,AVG(studentresult) FROM result
GROUP BY subjectno
HAVING AVG(studentresult)>60 -- 分組之後的條件

3)例題3
-- 01.統計每門課程平均分各是多少 降序排列
SELECT subjectno,AVG(studentresult) FROM result
GROUP BY subjectno
ORDER BY AVG(studentresult) DESC

-- 02.如果成績相同 再按照 課程編號 升序排序
SELECT subjectno,AVG(studentresult) FROM result
GROUP BY subjectno
ORDER BY AVG(studentresult) DESC,subjectno

4)例題4
-- 分組統計每個年級的 男女人數

SELECT gradeid 年級編號,sex 性別,COUNT(sex) 人數
FROM student
GROUP BY gradeid,sex

6、面試題
1)面試題1

老師代碼:(數據不完全對應題目,領會解題方法)

-- 創建表
CREATE TABLE IF NOT EXISTS examTest(
id INT(2) NOT NULL,
sex VARCHAR(20)
)

-- 同時新增多條數據
INSERT INTO examTest VALUES(1,‘男‘),(2,‘男‘),(3,‘女‘),(4,NULL);

01.使用where
SELECT sex AS ‘性別‘,COUNT(sex) AS ‘人數‘ FROM examTest
WHERE sex IS NOT NULL
GROUP BY sex
ORDER BY COUNT(sex) DESC

02.使用having
SELECT sex AS ‘性別‘,COUNT(sex) AS ‘人數‘ FROM examTest
GROUP BY sex
HAVING sex IS NOT NULL
ORDER BY COUNT(sex) DESC

03.使用where和in(取巧)
SELECT sex AS ‘性別‘,COUNT(sex) AS ‘人數‘ FROM examTest
WHERE sex IN(‘男‘,‘女‘)
GROUP BY sex
ORDER BY COUNT(sex) DESC


2)面試題2

作業,待解答

下次課確認答案後補上

三、作業

1、復習之前所講的mysql課程(老師txt文件裏的),預習事務,下節課考試

2、面試題第二題

四、老師辛苦了!

技術分享

2017年07月03號課堂筆記