I.導(dǎo)語
數(shù)據(jù)庫查詢是數(shù)據(jù)庫操作的核心聪建,SQL提供select語句進(jìn)行查詢,其一般的格式為:
select [all | distinct] <目標(biāo)列表達(dá)式> [,<目標(biāo)列表達(dá)式>] ...
from <表名或試圖名> [,<表名或試圖名>] ...
[where <條件表達(dá)式>]
[group by<列名1> [having <條件表達(dá)式>]]
[order by<列名2> [ASC | DESC]];
數(shù)據(jù)表
Student
學(xué)號 Sno | 姓名 Sname | 性別 Ssex | 年齡 Sage | 所在系 Sdept |
---|---|---|---|---|
20021521 | 李勇 | 男 | 20 | CS |
20021522 | 劉晨 | 女 | 19 | CS |
20021523 | 王敏 | 女 | 18 | MA |
20021524 | 張力 | 男 | 19 | IS |
Course
課程號 Cno | 課程名 Cname | 先行課 Cpno | 學(xué)分 Sage |
---|---|---|---|
1 | 數(shù)據(jù)庫 | 5 | 4 |
2 | 數(shù)學(xué) | 2 | |
3 | 信息系統(tǒng) | 1 | 4 |
4 | 操作系統(tǒng) | 6 | 3 |
5 | 數(shù)據(jù)結(jié)構(gòu) | 7 | 4 |
6 | 數(shù)據(jù)處理 | 2 | |
7 | PASCAL語言 | 6 | 4 |
CS
學(xué)號 Sno | 課程號 Cno | 成績 Grade |
---|---|---|
20021521 | 1 | 92 |
20021521 | 2 | 85 |
20021521 | 3 | 88 |
20021522 | 2 | 90 |
20021522 | 3 | 80 |
-- 查詢?nèi)w學(xué)生的學(xué)號和姓名
select Sno, Sname
from Student;
-- 查詢學(xué)生表的全部信息
-- 方式一
select *
from Student;
-- 方式二,這種方式可以改變結(jié)果列的順序,下面這個例子將Sno和Sname交互了位置
select Sname, Sno, Sage, Ssex, Sdept
from Student;
-- 查詢經(jīng)過計算的值
select Sname, 2017-Sage
from Student;
-- 改變表頭為 birthYear
select Sname, 2017-Sage birthYear
from Student;
-- select 等價于 select all
select all Sno
from SC;
上面的結(jié)果中Sno有重復(fù)行,如何消除重復(fù),使用distinct關(guān)鍵字
-- 消除重復(fù)行
select distinct Sno
from SC;
II.查詢滿足條件的元組
查詢滿足條件的元組可以通過where子句實(shí)現(xiàn)。
常用的查詢條件
條件 | 謂語 |
---|---|
比較 | =, >, <, >=, <=, !=, <>, !>, !<; NOT+上述比較運(yùn)算符 |
確定范圍 | between and, not between and |
確定集合 | in, not in |
字符匹配 | like, not like |
空值 | is null, is not null |
多重條件(邏輯運(yùn)算) | and, or, not |
(1)比較大小
-- 查詢計算機(jī)系的全體學(xué)生名單
select Sname
from Student
where Sdept='CS';
上面這個查詢操作呢铆,RDBMS可能的一種操作是全表掃描,取出一個元組蹲缠,檢查該元組的Sdept列的值是否為CS棺克,如果相等悠垛,則取出Sname形成新的元組輸出,否則跳過娜谊。假設(shè)這個表有上萬條數(shù)據(jù)确买,而Sdept=CS的人數(shù)較少,可以在Sdept上建立索引纱皆,系統(tǒng)會利用索引的來查找Sdept=CS的元組湾趾,避免全表掃描,加快查詢效率派草。
-- 查詢20歲以下的學(xué)生姓名和年齡
select Sname, Sage
from Student
where Sage<20;
-- 查詢考試成績有不合格的學(xué)生學(xué)號
select distinct Sno
from SC
where Grade < 60;
這里采用distinct消除重復(fù)行搀缠,因?yàn)橐粋€學(xué)號可能有幾門課不及格,只需要列出一次就行澳眷。
(2)確定范圍
-- 查詢年齡在 20到23歲(包含20/23)之間的學(xué)生的姓名、系別蛉艾、年齡
select Sname, Sdept, Sage
from Student
where Sage between 20 and 23;
-- 查詢年齡不在 20到23歲(包含20/23)之間的學(xué)生的姓名钳踊、系別、年齡
select Sname, Sdept, Sage
from Student
where Sage not between 20 and 23;
(3)確定集合
-- 查詢計算機(jī)系(CS)勿侯、數(shù)學(xué)系(MA)和信息系(IS)的學(xué)生姓名和性別
select Sname, Ssex
from Student
where Sdept in ('CS', 'MA', 'IS');
-- 查詢不在計算機(jī)系(CS)拓瞪、數(shù)學(xué)系(MA)和信息系(IS)的學(xué)生姓名和性別
select Sname, Ssex
from Student
where Sdept not in ('CS', 'MA', 'IS');
(4)字符匹配
一般格式
[not] like '<匹配串>' [escape '<換碼字符>']
其含義是查找指定屬性列值與匹配串相匹配的元組,匹配串可以是完整的字符串助琐,也可以是帶有通配符%和_祭埂。
%:代表任意長度(可以是0)的字符串。例如a%b表示以a開頭b結(jié)尾的任意長度字符串兵钮。如abc, abgggc蛆橡,ab都滿足該匹配。
_:代表任意單個字符掘譬。例如a_b泰演,表示以a開頭b結(jié)尾的長度為3的任意 字符串。如:abc葱轩,afc等都滿足該匹配睦焕。
-- 查詢序號為 200215121 的學(xué)生的詳細(xì)情況
select *
from Student
where Sno like '200215121';
這個等價于
select *
from Student
where Sno = '200215121';
如果like后面的匹配串不含通配符,like可用=(等于)來代替靴拱, not like可以用 垃喊!= 或者<>(不等于來代替)。
-- 查詢所有姓劉的學(xué)生的學(xué)號袜炕、姓名本谜、性別
select Sno, Sname, Ssex
from Student
where Sname like '劉%';
-- 查詢姓歐陽且全名長度為3的學(xué)生姓名,一個漢字占兩個_
select Sname
from student
where Sname like '歐陽__';
-- 查詢名字中第二字為陽的學(xué)生的姓名
select Sname
from Student
where Sname like '__陽%';
-- 查詢不姓劉的學(xué)生的姓名
select Sname
from Student
where Sname not like '劉%';
如果查詢的字符串包含通配符 %或者_(dá),這時就要使用escape'<換碼字符>'短語偎窘,對統(tǒng)配父進(jìn)行轉(zhuǎn)義耕突。
-- 查詢DB_design課程的課程號和學(xué)分
select Cno, Ccredit
from Course
where Cname like 'DB/_design'
escape '/';
escape '/'表示 “/”為轉(zhuǎn)義字符笤成,這樣緊跟在“/” 后面的“”不在具有統(tǒng)配符的含義,轉(zhuǎn)義為普通的“”字符眷茁。
-- 查詢課程名以DB_開頭且倒數(shù)第三個字符為i的課程詳情
select *
from Course
where Cname like 'DB/_%i__' escape '/';
(5)涉及空值的查詢
-- 查詢成績?yōu)榭盏膶W(xué)號和課程號
select Sno, Cno
from sc
where Grade is null;
(6)多條件查詢
邏輯運(yùn)算符and 和 or可以聯(lián)結(jié)多個查詢條件炕泳。and的優(yōu)先級高于or,但是可以通過括號來該變優(yōu)先級上祈。
-- 查詢計算機(jī)系年齡在20歲以下的學(xué)生姓名
select Sname
from Student
where Sdept = 'CS' and Sage < 20;
-- 查詢計算機(jī)系(CS)培遵、數(shù)學(xué)系(MA)和信息系(IS)的學(xué)生姓名和性別
select Sname, Ssex
from Student
where Sdept in ('CS', 'MA', 'IS');
-- 上面這個可以改造為 or 聯(lián)結(jié)條件
select Sname, Ssex
from Student
where Sdept='CS' or Sdept='MA' or Sdept='IS';
III.order by子句
用戶可以通過order by 子句對查詢結(jié)果按照一個或多個屬性列的升序(asc)或降序(desc)排列,缺省為升序排序登刺。
-- 查詢選修了3號課程的學(xué)生的學(xué)號及其成績并按照成績的降序排列
select Sno, Grade
from SC
where Cno=3
order by Grade desc;
對于空值的籽腕,升序空值排在最后,降序排在最前面纸俭。
-- 查詢所有學(xué)生的信息皇耗,按系的升序排列,同一個系的按照年齡降序排序
select *
from Student
order by Sdept, Sage desc;
IV.聚集函數(shù)(aggregate functions)
SQL提供了許多聚集函數(shù)揍很,主要包括:
函數(shù) | 含義 |
---|---|
count([distinct或all]*) | 統(tǒng)計元組個數(shù) |
sum([distinct或all] <列名>) | 計算一列的總和(此列必須是數(shù)值型) |
avg([distinct或all] <列名>) | 計算一列的平均值(此列必須是數(shù)值型) |
max([distinct或all] <列名>) | 求一列的最大值 |
min([distinct或all] <列名>) | 求一列的做小值 |
-- 查詢學(xué)生的總數(shù)
select count(*)
from Student;
-- 查詢選修了課程的學(xué)生人數(shù) 郎楼,消除重復(fù)學(xué)號
select count(distinct Sno)
from SC;
-- 計算1號課程的平均成績
select avg(Grade)
from SC
where Cno=1;
-- 查詢1號課程的最高分
select max(Grade)
from SC
where Cno='1';
-- 查詢200215122學(xué)生的總學(xué)分
select sum(Ccredit)
from sc, course
where sc.Sno='200215122' and sc.Cno = course.Cno;
V.group by子句
group by 子句將查詢結(jié)果按照某一列或多列的值進(jìn)行分組,值相同的為一組窒悔。
-- 求各個課程號和相應(yīng)的選課人數(shù)
select Cno,count(Sno)
from SC
group by Cno;
-- 查詢選修了3門課以上的學(xué)生學(xué)號
select Sno
from sc
group by Sno
having count(*)>3;
where子句和having短語的的區(qū)別在于作用對象不同呜袁。where做的的是基本表或者視圖,從中選擇符合條件的元組简珠;而having短語作用的是組阶界,從中選擇符合條件的組。