單表查詢
只在一個表中查詢數據
SELECT * FROM student where Sno='13143'; //根據學號查詢數據
多表查詢
同時查詢多個表
SELECT student.Sno,student.Sname,Grade
FROM student,SC where Grade>=90;
說明:這是在學生表student和成績表SC中查詢成績大于90的學生姓名和學號,因為這里Sno,Sname在兩個表中都存在,因此要指定查詢哪一個表中的數據,而Grade只在SC表中出現,因此不用指明哪張表
模糊查找
說明:模糊查找用
like
和not like
進行查找
-
SELECT * FROM student where Sname like '劉%';
查詢所有姓劉的學生 -
SELECT * FROM student where Sname like '%加%'
查詢名字中含有加字的學生信息,不固定加字的位置,在任意位置都能查到,這里一般搜索引擎都用是用這種模糊查找的方法來匹配搜索項 -
SELECT * FROM student where Sname like '歐陽_';
查找以姓歐陽并且名字為三個字的學生信息 -
SELECT * FROM student WHERE Sname like '_陽';
查找所有姓名為兩個字并且第二個字為陽的學生信息 -
SELECT * FROM student where Sname like '_陽%';
查詢所有姓名中第二個字為陽的學生信息 -
SELECT * FROM Course where Cname like '\_IS' ESCAPE '\';
查詢課程名字為_is的課程信息,這里如果要查詢的字符串本省就含有通配符"%
"或者"_
",這時就要使用ESCAPE<轉碼字符>
來對字符進行轉義了,這里的轉碼字符可以是任意的,但是我們通常都是用\
,上面的查詢語句中的\
就是轉碼字符
空值查詢
判斷數據是否為空用
is not null
和is null
SELECT * FROM student where Sname is null
;查詢姓名為空的學生信息
多重條件的查詢
多重條件的查詢用AND和OR,其區別不用多說了
SELECT Sname FROM student where Sdept='IS' and Sage>20;
查找院系是IS并且年齡超過20歲的學生姓名
ORDER BY子句(排序)
用戶可以使用ORDER BY子句對數據進行升序(
ASC
)或者降序(DESC
)排列
-
SELECT * FROM student where Sage>20 ORDER BY Sno DESC;
查詢年齡超過20歲的學生信息,并且按照降序排列輸出 -
SELECT * FROM student ORDER BY Sdept,Sage DESC;
查詢全體學生情況,查詢結果按照所在系的系號升序排列,同一系的按照年齡降序排列
聚集函數
COUNT(*)
統計元組個數COUNT(DISTINCT|ALL <列名>)
計算一列中值的個數,其中DISTINCT表示去除重復的元素,ALL則保留所有的元素SUM(DISTINCT|ALL <列名>)
計算一列值的總和AVG(DISTINCT|ALL<列名>)
計算一列中的平均值MAX(DISTINCT|ALL<列名> )
求一列中的最大值MIN(DISTINCT|ALL<列名> )
求一列中的最小值
實例:
select count(*) from student;
查詢學生總數select count(DISTINCT Sdept);
查詢總共有多少系select AVG(Grade) from SC;
查詢學生的平均分select SUM(Grade) from SC;
查詢學生的總分select MAX(Grade) from SC where Cno='1';
查詢課程1的最高分select MIN(Grade) from SC where Cno='1';
查詢課程1的最低分
注意:where
子句中不能用聚集函數,只有在select
子句和Group by
子句中才能使用聚集函數
GROUP BY子句
- GROUP BY子句將查詢結果按某一列或者多列的值分組,值相等的為一組。
- 對查詢結果分組的目的是為了細化聚集函數的對象。如果未對查詢結果進行分組,那么聚集函數將會作用于整個查詢結果,分組后聚集函數將會作用于每一組,即每一組都有一個函數值
實例:
-
select Cno,Count(Sno) from SC Group by Cno;
求各個課程號以及相應的選課人數 -
select Cno as '課程號',count(Sno) as '選課人數' from sc group by Cno;
求各個課程號以及相應的選課人數 -
select Cno,count(Sno),AVG(Grade) from sc group by Cno Having AVG(Grade)>80;
查詢課程平均分大于80分的課程號和所選學生人數,這里是先分組后然后對這些組進行篩選就用Having
子句進行條件篩選,不能使用where
子句進行篩選,當然這里的sleect子句中的AVG(Grade)可以去掉,可以寫成select Cno,count(Sno) from sc group by Cno Having AVG(Grade)>80;
-
select Sno from sc Group by Sno having count(*)>2;
查詢選修了兩門以上課程的學生學號 -
select Sno,AVG(Grade) from sc Group by Sno;
查詢每一個學生選修課程的平均成績,這里先按照學號進行分組,然后對每一個分組進行求平均成績
注意:這里的如果使用了聚集函數,那么select子句中出現的選項一定要在聚集函數或者Group by子句中出現,否則就會出現錯誤,如:
select Sno,count(Cno) from sc;
這條語句就是錯誤的,因為Sno
沒有出現在聚集函數或者Group by
子句中,如果改成select Sno,count(Cno) from SC Group by Sno;
就正確了,因為Sno出現在了Group by
子句中了
連接查詢
如果一個查詢涉及兩個以上的表則稱之為連接查詢,連接查詢包括等值連接查詢,自然連接查詢,自身連接查詢,非等值連接查詢,外連接查詢,復合條件查詢
等值和非等值連接查詢
當連接運算符為=時為等值連接查詢,否則為非等值連接查詢
實例:
select student.*,SC.* from student,SC where student.Sno=SC.Sno;
查詢每個學生及其選修課程的情況
自然連接查詢
在等值連接的基礎上去掉相等的屬性組就是自然連接查詢
實例:
select student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade from student,SC where student.Sno=SC.Sno;
嵌套查詢
在
SQL
語言中一個SELECT-FROM-WHERE
語句稱為一個查詢塊,將一個查詢塊嵌套在另外一個查詢塊的WHERE
子句或HAVING
短語的條件查詢稱之為嵌套查詢
實例:
SELECT SNAME FROM STUDENT WHERE SNO IN /*外層查詢*/
(SELECT SNO FROM SC WHERE CNO='2'); /*內層查詢或者子查詢*/
注意:
- 這里的查詢條件Sno只能有一個,并且外層查詢的where子句中出現的Sno屬性要和內層查詢select語句中的Sno屬性要對應。
- 子查詢中不能使用
ORDER BY
子句,ORDER BY
子句只能對最終的查詢結果排序
帶有IN謂詞的嵌套查詢
實例:
SELECT Sno,Sname,Sdept from student where Sdept IN
(SELECT Sdept From student Where Sname='劉晨');
查詢與劉晨在同一個系的學生信息,當然本例中也可以用自身連接查詢來完成,如下:
select first.Sno,first.Sname,first.Sdept
from student first,student second
where first.Sdept=second.Sdept and second.Sname='劉晨';
帶有比較運算符的子查詢
select Sno,Cno from sc x where Grade >
(select AVG(Grade) from sc y where x.Sno=y.Sno);
查詢了所有學生成績超過選修課程平均成績的課程號
帶有ANY或者ALL的謂詞子查詢
ANY
表示查詢條件只要滿足其中一個即可,而ALL
表示查詢條件要滿足所有的才行
實例:
SELECT SNAME,SAGE FROM STUDENT WHERE SAGE<ANY(SELECT SAGE FROM STUDENT WHERE SDEPT='CS') AND SDEPT!='CS';
查詢非計算機系的比計算機系任意一個學生年齡小的學生姓名和年齡,這里只要滿足比一個學生的年齡小即可SELECT SNAME,SAGE FROM STUDENT WHERE SAGE<ALL(SELECT SAGE FROM STUDENT WHERE SDEPT='CS') AND SDEPT!='CS';
查詢非計算機系的比計算機系的所有學生年齡小的學生信息,這里要滿足比所有的學生信息都要小,就是比計算機系年齡最小的都要小
帶有EXISTS謂詞的子查詢
EXISTS
表示存在的意思,帶有EXISTS
的子查詢步返回任何的數據,只產生邏輯真或者假
SELECT Sname From student where EXISTS (SELECT Sname from SC where Sno=student.Sno and Cno='2');
查詢選擇課程2的學生姓名,這里只判斷是否存在這樣的學生,如果子查詢中沒有找到課程2這項,那么查到的就是空,子查詢只判斷是否為true or false,當然還有NOT EXISTS
集合查詢
集合操作包括并操作
UNION
、交操作INTERSECT
、差操作EXCEPT
實例:
select * from student where Sdept= 'CS' UNION select * from student where Sage>19;
查找計算機系的學生以及年齡不大于19歲的學生信息,這里UNION
會自動去掉重復的元組,如果想要保留全部的數據需要用UNION ALL
select Sno from SC where Cno='1' UNION select Sno from SC where Cno='2';
查詢選修課程1或者選修課程2的學生學號,這里并集就是去掉重復的元組,使用UNION ALL
可以保留select Sno from SC where Cno='1' Intersect select Sno from SC where Cno='2';
查詢同時選修課程1和課程2的學生學號
基于派生表的查詢
select Sno,Cno from SC,(select Sno,AVG(Grade) from SC Group by Sno)
AS AVG_SC(avg_Sno,avg_grade)
where SC.Sno=AVG_SC.avg_Sno and SC.Grade>=AVG_SC.avg_grade;
這里的From子句中將會派生出一個AVG_SC表,該表由avg_Sno、avg_grade組成,主查詢將SC表和AVG_SC表進行連接,選出修課成績大于其平均成績的課程號
注意:如果子查詢中沒有聚集函數,那么派生表不用指定屬性列,子查詢后面的列名為其屬性,如下:
select Sname from student,(select Sno From SC where Cno='1') AS SCI where student.Sno=SCI.Sno;
這里的SCI默認的列屬性名是Sno,AS關鍵詞可以省略,但是必須要為派生表指定一個別名。