MySQL高級查詢


  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指定的表為主表,即右表為主表。(哪個表中所有行都顯示了,就是主表)

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM