1、exists和not exists子查詢
/*exists的常用用法*/
drop table if exists student;
此外,exists也可以作為where的子查詢:
/*exists的參數是一個任意的子查詢*/
/*若有返回行,exists的結果為true,會執行外層語句*/
/*若無返回行,exists結果為false,外層語句不再執行*/
select colums from tableName where exists(子查詢);
注意,exists和not exists的結果只取決於是否有返回記錄,不取決於記錄的內容。
2、子查詢注意事項
(1)子查詢語句可以嵌套在SQL語句中任何表達式出現的位置
子查詢可以被嵌套在select語句的列、表和查詢條件中,即select子句、from子句、where子句、group by子句和having子句。
/*select子句*/
select(子查詢)from 表名; /*from子句*/
/*這里表的別名不能省略*/
select * from(子查詢 )as 表的別名;
(2)只出現在子查詢中而沒有出現在父查詢中的表不能包含在輸出列中;
3、分組查詢
(1)group by——將查詢結果按照一個、多個字段分組
/*單獨使用group by*/
select * from student group by major
當像上面那樣單獨使用group by時,結果中每一個不同的major只會顯示一個(即每組中挑選一個顯示,貌似為每組的第一個)。這樣是沒有太多意義的,或者說,它只顯示了有多少個不同的major。
所用我們在分組查詢中會與數學統計函數結合一起使用。
單字段分組查詢:
/*查看每門課程的平均成績*/
select subjectNo,AVG(studentResult) as 課程平均成績 from result group by subjectNo; /*查詢男、女學生的人數各是多少*/
/*這里的可以這樣使用*號嗎?為何不直接指明列名?*/
/*可見的是表中的一行就僅代表一個人,所以這里用*表示的是對這種情況按行統計*/
select count(*) as 人數,sex from student group by sex; /*查詢每個年級的人數*/
/*這里的count(*)也是一樣*/
select count(*) as 年紀人數,gradeId from student group by gradeId; /*查詢每個科目的平均分,並且按照由高到低的順序排列顯示*/
/*這里要思考的是order by的位置,注意要對哪個數據排序*/
select subjectN,AVG(studentResult) AS 平均課程成績 from result group by subjectNo; order by AVG(studentResult) desc;
多字段分組查詢:
/*在一張學生信息表中有來自不同年紀、不同性別的學生,學號也都不同*/
/*現在統計每個年紀的男、女生人數*/
select count(*) as 人數,gradeId as 年級,sex as 性別 from student group by gradeId,sex order by gradeId;
注意到了,使用group by關鍵字時,在select列表中可以指定的列是有限制的,僅允許group by子句后的列,聚合函數計算出的列。
4、使用having子句進行分組篩選
簡單來說,having子句用來對分組后的數據進行篩選,即將組看成新的列,來進行篩選。而where子句只能對沒有分組統計前的數據進行篩選。
(1)查詢年紀總人數超過1的年級——先按年級分組,再按條件篩選
select count(*) as 人數,gradeId as 年級 from student group by grade having count(*)>2;
(2)select語句中,where、group by、having子句和聚合函數的執行次序如下:
where子句從數據源中去除不符合條件的數據;然后group by子句搜集數據行到各個組中;
接着統計函數為各個組計算統計值;最后having子句去掉不符合其組搜索條件的各組數據行。
如,查詢每門課程及格總人數和及格平均分在80分以上的記錄:
select count(*) as 人數,AVG(studentResult) as 平均分,subjectNo as 課程 from result where studentResult>=60
group by subjectNo having AVG(studentResult)>=80;
5、使用limit分頁查詢數據——基於多個表的數據查詢
(1)多表連接查詢——從多個表中選擇or比較數據項
通過各個表之間共同列的關聯性查詢數據,是關系數據庫查詢最主要的特征。
(2)內連接查詢,最典型、常用的連接查詢,根據表中共同的列來進行匹配。特別當兩個表存在主、外鍵關系時通常使用內連接查詢。
(3)外連接查詢,至少返回一個表中的所有記錄,根據匹配條件有選擇性地返回另一張表的記錄。有左外連接、右外連接。
6、內連接查詢
內連接通常使用“=”or“<>”等比較運算符來判斷兩列數據值是否相等。
在內連接查詢中,參與的表的地位是相等的。
實現內連接的兩種方式:
(1)where子句中指定連接條件
/*查詢學生姓名和成績,成績表中只有學號和成績,名字在學生信息表中*/
/*from后面有兩個表名*/
select student.studentName,result.subjectNo,result.studentResult from student,result where student.studentNo=result.studentNo;
(2)在from子句中使用inner join...on
/*inner join連接兩個表,且inner可以省略*/
/*on設置條件*/
/*as指定表的別名,如果查詢的列名在多個表中的名字不重復,則可以不使用表名限定*/
select S.studentName,R.subjectNo,R.studentResult from student as S inner join result as R on(S.studentNo=R.studentNo) /*連接三個表*/
/*查詢的數據分別來自三個表*/
select S.studentName as 學生姓名,SU.subjectName as 課程名稱, R.studentResult as 考試成績 from student as S inner join result as R on(S.studentNo=R.studentNo) inner join subject as SU on(SU.subjectNo=R.subjectNo)
7、外連接查詢
參與外連接查詢的表有主、從之分,以主表的每行數據匹配從表的數據列,將符合連接條件的數據直接返回到結果集中;而對不符合連接條件的列,會填上null值后再返回到結果集中。(內連接中會忽略不符合條件的數據)
(1)左外連接——left join...on,left outer join...on
結果集包括left join中指定的左表的所有行,若左表的某行在右表中沒有匹配行,則在相關的結果集行中右表的所有選擇列為空值。
/*顯示所有考試名單上的學生的成績,沒有參加的也要打印出來*/
/*主表(左表)為學生信息表,學生成績表為從表*/
/*沒有參加任何科目考試的學生,在成績表中也沒有相關記錄*/
/*他們對應的科目編號和成績均會以null填充*/
select S.studentName,R.subjectNo,R.studentResult from student as S left outer join result as R on(S.studentNo=R.studentNo)
(2)右外連接——right outer join...on,right outer join...on
結果集要包含右表中所有匹配的行,若右表中有的項在左表中沒有對應的項,以null值填充。
在這里,join指定的表為主表,即右表為主表。(哪個表中所有行都顯示了,就是主表)
