關(guān)系數(shù)據(jù)庫SQL數(shù)據(jù)查詢
數(shù)據(jù)查詢
一、單表查詢
1.查詢僅涉及一個(gè)表,選擇表中的若干列
[例1] 查詢?nèi)w學(xué)生的學(xué)號(hào)與姓名。
SELECT Sno,Sname
FROM Student;
[例2] 查詢?nèi)w學(xué)生的姓名、學(xué)號(hào)、所在系。
SELECT Sname,Sno,Sdept
FROM Student;
查詢?nèi)苛?/strong>
- 選出所有屬性列:
- 在SELECT關(guān)鍵字后面列出所有列名
- 將<目標(biāo)列表達(dá)式>指定為 *
[例3] 查詢?nèi)w學(xué)生的詳細(xì)記錄
SELECT Sno,Sname,Ssex,Sage,Sdept
FROM Student;
或
SELECT *
FROM Student;
查詢經(jīng)過計(jì)算的值
- SELECT子句的<目標(biāo)列表達(dá)式>不僅可以為表中的屬性列,也可以是表達(dá)式
[例4] 查全體學(xué)生的姓名及其出生年份。
SELECT Sname,2014-Sage /*假設(shè)當(dāng)時(shí)為2014年*/
FROM Student;
輸出結(jié)果:
Sname 2014-Sage
李勇 1994
劉晨 1995
王敏 1996
張立 1995
使用列別名改變查詢結(jié)果的列標(biāo)題:
SELECT Sname NAME,'Year of Birth:' BIRTH,
2014-Sage BIRTHDAY,LOWER(Sdept) DEPARTMENT
FROM Student;
輸出結(jié)果:
NAME BIRTH BIRTHDAY DEPARTMENT
李勇 Year of Birth: 1994 cs
劉晨 Year of Birth: 1995 cs
王敏 Year of Birth: 1996 ma
張立 Year of Birth: 1995 is
2.選擇表中的若干元組
消除取值重復(fù)的行
如果沒有指定DISTINCT關(guān)鍵詞,則缺省為ALL
[例5] 查詢選修了課程的學(xué)生學(xué)號(hào)。
SELECT Sno FROM SC;
等價(jià)于:
SELECT ALL Sno FROM SC;
執(zhí)行上面的SELECT語句后,結(jié)果為:
Sno
201215121
201215121
201215121
201215122
201215122
指定DISTINCT關(guān)鍵詞,去掉表中重復(fù)的行
SELECT DISTINCT Sno
FROM SC;
執(zhí)行結(jié)果:
Sno
201215121
201215122
常用的查詢條件:
1. 比較大?。?/strong>
[例6] 查詢計(jì)算機(jī)科學(xué)系全體學(xué)生的名單。
SELECT Sname
FROM Student
WHERE Sdept=‘CS’;
[例7]查詢所有年齡在20歲以下的學(xué)生姓名及其年齡。
SELECT Sname,Sage
FROM Student
WHERE Sage < 20;
[例8]查詢考試成績有不及格的學(xué)生的學(xué)號(hào)。
SELECT DISTINCT Sn
FROM SC
WHERE Grade<60;
2. 確定范圍:
謂詞: BETWEEN … AND …
NOT BETWEEN … AND …
[例9] 查詢年齡在20~23歲(包括20歲和23歲)之間的學(xué)生的姓名、系別和年齡
SELECT Sname, Sdept, Sage
FROM Student
WHERE Sage BETWEEN 20 AND 23;
[例10] 查詢年齡不在20~23歲之間的學(xué)生姓名、系別和年齡
SELECT Sname, Sdept, Sage
FROM Student
WHERE Sage NOT BETWEEN 20 AND 23;
3. 確定集合:
謂詞:IN <值表>, NOT IN <值表>
[例11]查詢計(jì)算機(jī)科學(xué)系(CS)、數(shù)學(xué)系(MA)和信息系(IS)學(xué)生的姓名和性別。
SELECT Sname, Ssex
FROM Student
WHERE Sdept IN ('CS','MA’,'IS' );
[例12]查詢既不是計(jì)算機(jī)科學(xué)系、數(shù)學(xué)系,也不是信息系的學(xué)生的姓名和性別。
SELECT Sname, Ssex
FROM Student
WHERE Sdept NOT IN ('IS','MA’,'CS' );
- 字符匹配:
-
謂詞: [NOT] LIKE ‘<匹配串>’ [ESCAPE ‘ <換碼字符>’]
-
<匹配串>可以是一個(gè)完整的字符串,也可以含有通配符%和 _
-
% (百分號(hào)) 代表任意長度(長度可以為0)的字符串
-
例如a%b表示以a開頭,以b結(jié)尾的任意長度的字符串
_ (下橫線) 代表任意單個(gè)字符。 -
例如a_b表示以a開頭,以b結(jié)尾的長度為3的任意字符串
匹配串為固定字符串
[例13] 查詢學(xué)號(hào)為201215121的學(xué)生的詳細(xì)情況。
SELECT *
FROM Student
WHERE Sno LIKE ‘201215121';
等價(jià)于:
SELECT *
FROM Student
WHERE Sno = ' 201215121 ';
匹配串為含通配符的字符串
[例14] 查詢所有姓劉學(xué)生的姓名、學(xué)號(hào)和性別。
SELECT Sname, Sno, Ssex
FROM Student
WHERE Sname LIKE '劉%';
[例15] 查詢姓"歐陽"且全名為三個(gè)漢字的學(xué)生的姓名。
SELECT Sname
FROM Student
WHERE Sname LIKE '歐陽__';
使用換碼字符將通配符轉(zhuǎn)義為普通字符
[例16] 查詢DB_Design課程的課程號(hào)和學(xué)分。
SELECT Cno,Ccredit
FROM Course
WHERE Cname LIKE 'DB\_Design' ESCAPE '\ ' ;
[例17] 查詢以"DB_"開頭,且倒數(shù)第3個(gè)字符為 i的課程的詳細(xì)情況。
SELECT *
FROM Course
WHERE Cname LIKE 'DB\_%i_ _' ESCAPE '\ ' ;
ESCAPE '\' 表示“ \” 為換碼字符
5. 涉及空值的查詢:
謂詞: IS NULL 或 IS NOT NULL
- “IS” 不能用 “=” 代替
[例18] 某些學(xué)生選修課程后沒有參加考試,所以有選課記錄,但沒 有考試成績。查詢?nèi)鄙俪煽兊膶W(xué)生的學(xué)號(hào)和相應(yīng)的課程號(hào)。
SELECT Sno,Cno
FROM SC
WHERE Grade IS NULL
[例19] 查所有有成績的學(xué)生學(xué)號(hào)和課程號(hào)。
SELECT Sno,Cno
FROM SC
WHERE Grade IS NOT NULL;
6.多重條件查詢
- 邏輯運(yùn)算符:AND和 OR來連接多個(gè)查詢條件
AND的優(yōu)先級(jí)高于OR - 可以用括號(hào)改變優(yōu)先級(jí)
[例20] 查詢計(jì)算機(jī)系年齡在20歲以下的學(xué)生姓名。
SELECT Sname
FROM Student
WHERE Sdept= ‘CS’ AND Sage<20;
3.ORDER BY子句
ORDER BY子句
? 可以按一個(gè)或多個(gè)屬性列排序
? 升序:ASC;降序:DESC;缺省值為升序
對(duì)于空值,排序時(shí)顯示的次序由具體系統(tǒng)實(shí)現(xiàn)來決定
[例21]查詢選修了3號(hào)課程的學(xué)生的學(xué)號(hào)及其成績,查詢結(jié)果按分?jǐn)?shù)降序排列。
SELECT Sno, Grade
FROM SC
WHERE Cno= ' 3 '
ORDER BY Grade DESC;
[例22]查詢?nèi)w學(xué)生情況,查詢結(jié)果按所在系的系號(hào)升序排列,同一系中的學(xué)生按年齡降序排列。
SELECT *
FROM Student
ORDER BY Sdept, Sage DESC;
4.聚集函數(shù)統(tǒng)計(jì)元組個(gè)數(shù)
COUNT(*)
-
統(tǒng)計(jì)一列中值的個(gè)數(shù)
COUNT([DISTINCT|ALL] <列名>)
-
計(jì)算一列值的總和(此列必須為數(shù)值型)
SUM([DISTINCT|ALL] <列名>)
-
計(jì)算一列值的平均值(此列必須為數(shù)值型)
AVG([DISTINCT|ALL] <列名>)
-
求一列中的最大值和最小值
MAX([DISTINCT|ALL] <列名>)
MIN([DISTINCT|ALL] <列名>)
[例23] 查詢學(xué)生總?cè)藬?shù)。
SELECT COUNT(*)
FROM Student;
[例24] 查詢選修了課程的學(xué)生人數(shù)。
SELECT COUNT(DISTINCT Sno)
FROM SC;
[例25] 計(jì)算1號(hào)課程的學(xué)生平均成績。
SELECT AVG(Grade)
FROM SC
WHERE Cno= ' 1 ';
[例26] 查詢選修1號(hào)課程的學(xué)生最高分?jǐn)?shù)。
SELECT MAX(Grade)
FROM SC
WHERE Cno='1';
[例27 ] 查詢學(xué)生201215012選修課程的總學(xué)分?jǐn)?shù)。
SELECT SUM(Ccredit)
FROM SC,Course
WHERE Sno='201215012' AND SC.Cno=Course.Cno;
5.GROUP BY子句
GROUP BY子句分組:
細(xì)化聚集函數(shù)的作用對(duì)象
- 如果未對(duì)查詢結(jié)果分組,聚集函數(shù)將作用于整個(gè)查詢結(jié)果
- 對(duì)查詢結(jié)果分組后,聚集函數(shù)將分別作用于每個(gè)組
- 按指定的一列或多列值分組,值相等的為一組
[例28] 求各個(gè)課程號(hào)及相應(yīng)的選課人數(shù)。
SELECT Cno,COUNT(Sno)
FROM SC
GROUP BY Cno;
查詢結(jié)果可能為:
Cno COUNT(Sno)
1 22
2 34
3 44
4 33
5 48
HAVING短語與WHERE子句的區(qū)別:
- 作用對(duì)象不同
- WHERE子句作用于基表或視圖,從中選擇滿足條件的元組
- HAVING短語作用于組,從中選擇滿足條件的組。
二、連接查詢
-
連接查詢:同時(shí)涉及兩個(gè)以上的表的查詢
-
連接條件或連接謂詞:用來連接兩個(gè)表的條件
一般格式:
? [<表名1>.]<列名1> <比較運(yùn)算符> [<表名2>.]<列名2>
? [<表名1>.]<列名1> BETWEEN [<表名2>.]<列名2> AND [<表名2>.]<列名3>
- 連接字段:連接謂詞中的列名稱
? 連接條件中的各連接字段類型必須是可比的,但名字不必相同
1.等值與非等值連接查詢
等值連接:連接運(yùn)算符為=
[例 29] 查詢每個(gè)學(xué)生及其選修課程的情況
SELECT Student.*, SC.*
FROM Student, SC
WHERE Student.Sno = SC.Sno;
結(jié)果為
1)嵌套循環(huán)法(NESTED-LOOP)
- 首先在表1中找到第一個(gè)元組,然后從頭開始掃描表2,逐一查找滿足連接件的元組,找到后就將表1中的第一個(gè)元組與該元組拼接起來,形成結(jié)果表中一個(gè)元組。
- 表2全部查找完后,再找表1中第二個(gè)元組,然后再從頭開始掃描表2,逐一查找滿足連接條件的元組,找到后就將表1中的第二個(gè)元組與該元組拼接起來,形成結(jié)果表中一個(gè)元組。
- 重復(fù)上述操作,直到表1中的全部元組都處理完畢
(2)排序合并法(SORT-MERGE)
-
常用于=連接
-
首先按連接屬性對(duì)表1和表2排序
-
對(duì)表1的第一個(gè)元組,從頭開始掃描表2,順序查找滿足連接條件的元組,找到后就將表1中的第一個(gè)元組與該元組拼接起來,形成結(jié)果表中一個(gè)元組。當(dāng)遇到表2中第一條大于表1連接字段值的元組時(shí),對(duì)表2的查詢不再繼續(xù)
-
找到表1的第二條元組,然后從剛才的中斷點(diǎn)處繼續(xù)順序掃描表2,查找滿足連接條件的元組,找到后就將表1中的第一個(gè)元組與該元組拼接起來,形成結(jié)果表中一個(gè)元組。直接遇到表2
中大于表1連接字段值的元組時(shí),對(duì)表2的查詢不再繼續(xù)
-
重復(fù)上述操作,直到表1或表2中的全部元組都處理完畢為止
(3)索引連接(INDEX-JOIN)
- 對(duì)表2按連接字段建立索引
- 對(duì)表1中的每個(gè)元組,依次根據(jù)其連接字段值查詢表2的索引,從中找到滿足條件的元組,找到后就將表1中的第一個(gè)元組與該元組拼接起來,形成結(jié)果表中一個(gè)元組
自然連接
[例 30] 對(duì)[例 3.49]用自然連接完成。
SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM Student,SC
WHERE Student.Sno = SC.Sno;
2.自身連接
- 自身連接:一個(gè)表與其自己進(jìn)行連接
- 需要給表起別名以示區(qū)別
- 由于所有屬性名都是同名屬性,因此必須使用別名前綴
[例 32]查詢每一門課的間接先修課(即先修課的先修課)
SELECT FIRST.Cno, SECOND.Cpno
FROM Course FIRST, Course SECOND
WHERE FIRST.Cpno = SECOND.Cno;
3.外連接
外連接與普通連接的區(qū)別
- 普通連接操作只輸出滿足連接條件的元組
- 外連接操作以指定表為連接主體,將主體表中不滿足連接條件的元組一并輸出
- 左外連接
? 列出左邊關(guān)系中所有的元組
- 右外連接
? 列出右邊關(guān)系中所有的元組
[例 33] 改寫[例 29]
SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade
FROM Student LEFT OUT JOIN SC ON
(Student.Sno=SC.Sno);
執(zhí)行結(jié)果
三、嵌套查詢
嵌套查詢概述
- 一個(gè)SELECT-FROM-WHERE語句稱為一個(gè)查詢塊
- 將一個(gè)查詢塊嵌套在另一個(gè)查詢塊的WHERE子句或HAVING短語的條件中的查詢稱為嵌套查詢
SELECT Sname /*外層查詢/父查詢*/
FROM Student
WHERE Sno IN
( SELECT Sno /*內(nèi)層查詢/子查詢*/
FROM SC
WHERE Cno= ' 2 ');
-
上層的查詢塊稱為外層查詢或父查詢
-
下層查詢塊稱為內(nèi)層查詢或子查詢
-
SQL語言允許多層嵌套查詢
- 即一個(gè)子查詢中還可以嵌套其他子查詢
-
子查詢的限制
- 不能使用ORDER BY子句
不相關(guān)子查詢:
子查詢的查詢條件不依賴于父查詢
- 由里向外 逐層處理。即每個(gè)子查詢在上一級(jí)查詢處理之前求解,子查詢的結(jié)果用于建立其父查詢的查找條件。
相關(guān)子查詢:子查詢的查詢條件依賴于父查詢
- 首先取外層查詢中表的第一個(gè)元組,根據(jù)它與內(nèi)層查詢相關(guān)的屬性值處理內(nèi)層查詢,若WHERE子句返回值為真,則取此元組放入結(jié)果表
- 然后再取外層表的下一個(gè)元組
- 重復(fù)這一過程,直至外層表全部檢查完為止
1.帶有IN謂詞的子查詢
[例 35] 查詢與“劉晨”在同一個(gè)系學(xué)習(xí)的學(xué)生。
此查詢要求可以分步來完成
① 確定“劉晨”所在系名
SELECT Sdept
FROM Student
WHERE Sname= ' 劉晨 ';
結(jié)果為: CS
② 查找所有在CS系學(xué)習(xí)的學(xué)生。
SELECT Sno, Sname, Sdept
FROM Student
WHERE Sdept= ' CS ';
結(jié)果為:
2.帶有比較運(yùn)算符的子查詢
當(dāng)能確切知道內(nèi)層查詢返回單值時(shí),可用比較運(yùn)算符(>,<,=,>=,<=,!=或< >)。
在[例 36]中,由于一個(gè)學(xué)生只可能在一個(gè)系學(xué)習(xí),則可以用 = 代替IN :
SELECT Sno,Sname,Sdept
FROM Student
WHERE Sdept =
(SELECT Sdept
FROM Student
WHERE Sname= '劉晨');
[例 37 ]找出每個(gè)學(xué)生超過他選修課程平均成績的課程號(hào)。
SELECT Sno, Cno
FROM SC x
WHERE Grade >=(SELECT AVG(Grade)
FROM SC y
WHERE y.Sno=x.Sno);
3.帶有ANY(SOME)或ALL謂詞的子查詢
使用ANY或ALL謂詞時(shí)必須同時(shí)使用比較運(yùn)算
語義為:
-
ANY 大于子查詢結(jié)果中的某個(gè)值
-
ALL 大于子查詢結(jié)果中的所有值
-
< ANY 小于子查詢結(jié)果中的某個(gè)值
-
< ALL 小于子查詢結(jié)果中的所有值
-
= ANY 大于等于子查詢結(jié)果中的某個(gè)值
-
= ALL 大于等于子查詢結(jié)果中的所有值
-
<= ANY 小于等于子查詢結(jié)果中的某個(gè)值
-
<= ALL 小于等于子查詢結(jié)果中的所有值
-
= ANY 等于子查詢結(jié)果中的某個(gè)值
-
=ALL 等于子查詢結(jié)果中的所有值(通常沒有實(shí)際意義)
-
!=(或<>)ANY 不等于子查詢結(jié)果中的某個(gè)值
-
!=(或<>)ALL 不等于子查詢結(jié)果中的任何一個(gè)值
[例 38] 查詢非計(jì)算機(jī)科學(xué)系中比計(jì)算機(jī)科學(xué)系任意一個(gè)學(xué)生年齡小的學(xué)生姓名和年齡
SELECT Sname,Sage
FROM Student
WHERE Sage < ANY (SELECT Sage
FROM Student
WHERE Sdept= ' CS ')
AND Sdept <> ‘CS ' ; /*父查詢塊中的條件 */
結(jié)果:文章來源:http://www.zghlxwxcb.cn/news/detail-487519.html
執(zhí)行過程:
(1)首先處理子查詢,找出CS系中所有學(xué)生的年齡,構(gòu)成一個(gè)集合(20,19)
(2)處理父查詢,找所有不是CS系且年齡小于 20 或 19的學(xué)生文章來源地址http://www.zghlxwxcb.cn/news/detail-487519.html
到了這里,關(guān)于關(guān)系數(shù)據(jù)庫SQL數(shù)據(jù)查詢的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!