查詢
基本命令格式:
SELECT [ALL|DISTINCT] <目標列表達式>
[,<目標列表達式>] …
FROM <表名或視圖名>[,<表名或視圖名> ] …
[ WHERE <條件表達式> ]
[ GROUP BY <列名1> [ HAVING <條件表達式> ] ]
[ ORDER BY <列名2> [ ASC|DESC ] ];
一、單表查詢
1、選擇表中的若干列
Select <目標列表達式> from <表名或視圖名>
【示例1:】查詢全體學生姓名與學號
Select 姓名,學號 from student
【示例2:】查詢全體學生的全部字段項目
Select * from student
2、選擇表中的若干元組
(1)消除取值重複的行
Select distinct<目標列表達式>from<表或視圖名>
【示例1:】查詢選修了課程的學生學號
Select distinct 學號 from sc
【示例2:】觀察命令的執行結果
Select distinct 學號,課程號 from sc
(2)查詢滿足條件的元組
select … where <條件表達式>
條件表達式中常用運算符號:
◆比較:>,>=,<,<=,=,!=,<>(,!>,!<)
◆範圍:between …and
◆集合:in
◆匹配:like (%:任意個字符,_:單個字符)
◆空值:is null;is not null
◆邏輯:and,or,not
【示例1:】顯示所有男生記錄
Select * from student where 性別=‘男’
【示例2:】顯示20歲以下的學生姓名及年齡
Select 姓名,2007-year(出生日期) 年齡 from student where 2007-year(出生日期) <20
【示例3:】查詢學分在1-3之間的所有課程名及學分
Select 課程名,學分 from coursewhere 學分>=1 and 學分<=3
Select 課程名,學分 from coursewhere 學分 between 1and 3
Select 課程名,學分 from coursewhere 學分 in (1,2,3)
【示例4:】查找所有姓王的學生的記錄
Select * from student where 姓名 like ‘王%’
【示例5:】查找姓名中第2個字是“小”的女同學
Select * from student where 姓名 like ‘_ _小%’ and 性別=‘女’
【示例6:】查詢以“DB_”開頭的課程
Select * from course where 課程名 like 'DB\_%' escape '\' 說明: ‘\‘ 爲換碼字符
【示例7:】查詢沒有成績的學生的學號和課程號
Select 學號,課程號 from scwhere 成績 is null
3、對查詢結果進行排序
select … order by <列名>[asc|desc]
【示例1:】查詢全體學生信息,結果按姓名降序排列。
Select * from student order by 姓名 desc
【示例2:】查詢全體學生信息,結果按系升序排列,同一系內部按姓名升序排列
Select * from student order by 系,姓名
4、統計操作
在<目標列表達式>中使用集函數:
Count([distinct|all]*) 統計元組個數
Count([distinct|all]<列名>) 統計一列中值的個數
sum([distinct|all]<列名>) 求一列值的總和
avg([distinct|all]<列名>) 求一列值的平均值
max([distinct|all]<列名>) 求一列值中的最大值
min([distinct|all]<列名>) 求一列值中的最小值
其中:
◆Distinct:表示在計算時要取消指定列中的重複值。
◆All:缺省值,不取消重複值。
【示例1:】查詢信息系的學生人數
Select count(*) from student where 系='信息’
【示例2:】查詢選修了課程的學生人數
Select count(distinct(學號)) 人數 from sc
【示例3:】查詢4號課程的最高分、最低分和平均分。
Select max(成績),min(成績),avg(成績) from sc where 課程號='04'
5、對查詢的結果進行分組
select … group by <列名>[having <條件表達式>]
having <條件表達式>:作用的對象是組,即表示對分組後的記錄進行篩選。
【示例1:】統計各個系的學生人數。
Select 系,count(*) from student groupby 系
【示例2:】統計每位學生的所有課程的平均成績
Select 學號,avg(成績) from scgroup by 學號
【示例3:】統計每門課程的最高分、最低分
Select 課程號,max(成績) ,min(成績) from sc group by 課程號
【示例4:】統計信息系和管理系的學生人數
Select 系,count(*) as 學生人數 from student group by 系 having 系='信息' or 系='工管'
【示例5:】查詢選修了3門以上課程的學生學號和門數
Select 學號,count(*) from sc group by 學號 having count(*)>3
二、多表查詢(連接查詢)
1、命令及運算符
Select …from <表名1>,<表名2> where [<表名1>.]<列名1><比較運算符>[<表名2>.]<列名2>=、>、>=、<、<=、!=、between … and
2、連接查詢的分類
◆按連接的運算符分類:等值連接與非等值連接兩類。
◆按連接的類型分類:內連接、外連接和交叉連接。
3、內連接
只返回與連接條件相匹配的元組。
【示例1:】查詢所有學生的選課情況
Select student.*,sc.* from student,sc wherestudent.學號=sc.學號
【示例2:】查詢選修“數據庫”的學生的學號及成績
Select x.學號,x.成績 from coursec,sc x where c.課程號=x.課程號 and c.課程名='數據庫'
【示例3:】查詢“王一”的姓名、課程名及成績
Select s.姓名, c.課程名 ,x.成績 from student s,sc x,course cwhere s.學號=x.學號 and c.課程號=x.課程號 and s.姓名='王一'
【示例4:】查詢每一門課程的先修課的名稱(自連接)
Select a.課程號,a.課程名,b.課程名 from course a,course b where a.先修課=b.課程號
4、外連接
不但返回與連接條件相匹配的元組,而且還會根據外連接類型不同返回與連接條件不匹配的元組。左外連接、右外連接、全外連接。
【示例1:】顯示所有學生的姓名及選課情況(沒有選課的學生名單也要列出來)
Select student.姓名,sc.課程號,sc.成績 fromstudent,sc where student.學號*=sc.學號
5、交叉連接(廣義笛卡爾積)
返回兩個表中元組的交叉乘積。
6、SQL-92中連接查詢的表示方法
將連接條件放在From子句的後面,基本格式爲:
R [natural] {連接類型} join S {on 條件}
連接類型:
◆Cross join:笛卡爾積
◆Left outerjoin:左外連接
◆Right outerjoin:右外連接
◆Full outerjoin:全外連接
◆Inner join:內連接
三、嵌套查詢
在一個select查詢語句的where子句或having子句中插入另一個查詢語句稱爲嵌套查詢。
【例如:】查詢選修了2號課程的學生名單。
Select s.姓名 from student s,sc x where s.學號=x.學號 and x.課程號='02'
Select 姓名 from student where 學號 in
( Select 學號 from scwhere 課程號='02')
上層的查詢模塊稱爲外層查詢或父查詢。下層的查詢模塊稱爲內層查詢或子查詢。子查詢中不能使用order by 子句。
1、帶有IN謂詞的子查詢
【示例1:】查詢與“王一”同一個系的學生姓名
Select 姓名 from student where 系 in (select 系 from student where 姓名='王一')
◆查詢“數據庫”課程的學生選修名單
Select 姓名 from student where 學號 in (select 學號 from sc where 課程號 in (select 課程號 from course where 課程名='數據庫'))
不相關子查詢:子查詢的查詢條件不依賴於父查詢。
2、帶有比較運算符的子查詢
當確信子查詢返回的是單值時,可使用比較運算符。
【示例1:】查詢與“王一”同一個系的學生姓名
Select 姓名 from student where 系 = (select 系 from student where 姓名='王一')
3、帶有some(any)或all謂詞的子查詢
使用some或all時,必須同時使用比較運算符。
【示例1:】查詢其他系中比信息系所有學生年齡都小的學生的姓名。(即比信息系中年齡最小的還要小)
Select 姓名 from student where 出生日期>all (select 出生日期 from student where 系='信息')
And 系<>'信息'
Select 姓名 from student where 出生日期 >(select max(出生日期) from student where 系='信息')
And 系<>'信息’
帶有some、all的子查詢往往可以用集函數來代替,而且查詢的效率更高。
4、帶有exists謂詞的子查詢
該類子查詢不返回任何數據,只產生邏輯真或假。
【示例1:】查詢選修了1號課程的學生姓名
Select 姓名 from student where 學號 in
( Select 學號 from scwhere 課程號='01')
Select 姓名 from student where exists(select * from sc where 學號=student.學號 and 課程號='01')
相關子查詢:子查詢的查詢條件依賴於外層父查詢的某個屬性值。
所有的帶in、比較運算符、some和all謂詞的子查詢都可以用帶exists的子查詢替換。反之卻不一定。
【示例2:】查詢選修了全部課程的學生姓名
Select 姓名 from student where not exists (select * from course where notexists (select * from sc where 學號=student.學號 and 課程號=course.課程號))
語義:沒有一門課程沒有被選修。
四、集合查詢
集合運算包括並(union)、差(intersect)、交(except)。其中差和交運算是SQL-92中規定的。
【示例1:】查詢選修了1號課程和3號課程的並集
Select * from sc where 課程號=“1” union
(Select * from sc where 課程號=“3”)
Select * from sc where 課程號=“1” or 課程號= “3”
【示例2:】查詢選修了1號課程和3號課程的交集
Select * from sc where 課程號=“1” and 學號 in(select 學號 from sc where 課程號=“3”)
Select * from sc where 課程號=“1” intersect
(Select * from sc where 課程號=“3”)
【示例3:】查詢選修了1號課程和3號課程的差集
Select * from sc where 課程號=“1” and 學號 notin(select 學號 from scwhere 課程號=“3”)
Select * from sc where 課程號=“1” except
(select 學號 from sc where 課程號=“3”)