第一章
1.數據
數據是數據庫中存儲的基本對象。
數據定義為數據是描述事物的符號記錄。
2.數據庫
數據庫數據具有永久存儲、有組織和可共享三個基本特點。
3.數據庫管理系統
數據庫管理系統位於用戶應用程序與操作系統軟件之間。
4.數據庫系統
數據庫系統由數據庫、數據庫管理系統、應用程序、數據庫管理員組成。
“列”稱為字段,“行”稱為記錄。
文件方式管理數據有以下缺點:
1.編寫應用程序不方便。2.數據冗余不可避免。3.應用程序依賴性。4.不支持對文件的並發訪問。5.數據間聯系弱。6.難以滿足不同用戶對數據的需求。7.無安全控制功能。
數據庫管理,對用戶來說,他只針對數據庫進行操作,無需對數據文件進行操作。
與文件管理數據相比,用數據庫技術管理數據具有以下特點:
1.相互關聯的數據集合。2.較少的數據冗余。3.程序與數據相互獨立。4.保證數據安全、可靠。5.最大限度的保證數據的正確性。6.數據可以共享並能保證數據的一致性。
SQL Server只支持在Windows平台上運行,而Oracle有支持Windows平台和Linux平台的不同版本.
第二章
1.數據庫中的數據具有靜態特征和動態特征
靜態特征:數據的基本結構、數據間的聯系以及對數據取值范圍的約束。
動態特征:對數據可以進行的操作以及操作規則。
一般將對數據的靜態特征和動態特征對的描述稱為數據模型的三要素,即在描述數據時要包括數據的基本結構、數據的約束條件(這兩個屬於靜態特征)和定義在數據上的操作(屬於動態特征)。
2.E-R模型
實體中每個具體的記錄值(一行數據),我們稱為實體的一個實例。
在實體屬性中,將能夠唯一標識實體的一個屬性或最小的一組屬性(稱為屬性集或屬性組)稱為實體的標識屬性,這個屬性或屬性組也稱為實體的碼。例如,“學號”就是學生實體的碼。
3.層次模型
層次模型是數據庫管理系統中最早出現的數據模型。
層次模型中的兩點限制:1.有且僅有一個節點無父節點,這個節點即為樹的根。2.其他節點有且僅有一個父節點。
層次模型的一個基本特點:任何一個給定的記錄值只有從層次模型的根部開始按路徑查看時,才能明確其含義,在任何節點都不能脫離父節點而存在。
4.數據的三級模式結構
數據的三級模式結構是指數據庫外模式、模式和內模式。
廣義地講,內模式是最接近物理存儲的,也就是數據的物理存儲方式,包括數據存儲位置、數據存儲方式等。外模式是最接近用戶的,也就是用戶所看到的數據視圖。模式是介於內模式和外模式之間的中間層,是數據的邏輯組織方式。
第三章
1.數據庫數據的操作主要包括查詢、插入、刪除和更改數據四種。
2.在關系數據模型中,一般將數據完整性分為三類,即實體完整性、參照完整性和用戶定義的完整性。
前兩個是關系模型必須滿足的完整性約束,是系統級的約束。用戶定義的完整性主要是限制屬性的取值在有意義的范圍內,如限制性別的取值范圍為“男”和“女”。屬於應用級的約束。
3.如果一個屬性或屬性集的值能夠唯一標識一個關系的元組而又不包括多余的屬性,則稱該屬性或屬性集為候選鍵。例如,學生(學號、姓名、年齡、性別、所在系)的候選鍵是學號。
候選鍵又稱為候選關鍵字或候選碼。在一個關系上可以有多個候選鍵。
當一個關系中有多個候選鍵時,可以從中選擇一個作為主鍵。每個關系只能有一個主鍵。
主鍵可以由一個屬性組成,也可以由多個屬性組成。我們稱由多個屬性共同組成的主鍵為復合主鍵。
4.實體完整性是指關系數據庫中所有的表都必須有主鍵,而且表中不允許存在以下記錄。
(1)無主鍵值的記錄。(2)主鍵值相同的記錄。
5.設F是關系R的一個或一組屬性,如果F與關系S的主鍵相對應,則稱F是關系R的外鍵。
“學生”關系中的“班號”屬性與“班”關系中的主鍵“班號”對應,因此,“學生”關系中的“班號”是外鍵,引用了“班”關系中的“班號”(主鍵)。這里,“班”關系是被參照關系,“學生”關系是參照關系。
對於外鍵,一般符合以下要求。
或者值為空。 或者等於其所參照的關系中的某個元組的主鍵值。
主鍵要求必須是非空且不重的,但外鍵無此要求。外鍵可以有重復值。
第四章
1.SQL中的字符串常量
SQL中的字符串常量要用單引號括起來,如‘計算機系’。
2.定義架構:CREATE SCHEMA
為用戶“ZHANG”定義一個架構,架構名為“S_C” CREATE SCHEMA S_C AUTHORIZATION ZHANG
3.刪除架構:DROP SCHEMA
4.定義約束
NOT NULL和DEFAULT只能定義在“列級完整性約束定義”處,其他約束均可在“列級完整性約束定義”和“表級完整性約束定義”處定義。
5.兩張表的創建
CREATE TABLE Jobs(
Jid char(6) PRIMARY KEY, --在列級定義主鍵
Descp nchar(20) NOT NULL,
EduReq nchar(6) DEFEAT '本科',
MinSalary int,
MaxSalary int,
CHECK(MaxSalary>=MinSalary) --多列的CHECK約束必須定義在表級
)
CREATE TABLE Employees(
Eid char(10),
Ename nvarchar(20) NOT NULL,
Sex nchar(1) CHECK(Sex='男' OR Sex='女'), --一列
BirthDate date,
JobDate datetime DEFAULT GetDate(), --默認為系統的當前日期和時間
Sid char(18) UNIQUE, --取值不重復
Jid char(6),
Tel char(11),
PRIMAARY KEY(Eid), --在表級定義主鍵
FOREIGN KEY(Jid) REFERENCES Jobs(Jid)
)
6.修改表結構
為Employees表添加工資列,此列的列名為Salary,數據類型為Int,允許空。
ALTER TBLE Employees
ADD Salary INT
將Jobs表的Descp列的數據類型改為NCHAR(40)。
ALTER TABLE Jobs
ALTER COLUMN Descp NCHAR(40)
刪除Employees表的Tel列。
ALTER TBLE Employees
DROP COLUMN Tel
為Jobs表中MinSalary列添加約束:大於等於1600.
ALTER TABLE Jobs
ADD CHECK(MinSalary>=1600)
7.刪除表
DROP TABLE Employees
刪除表時必須先刪外鍵所在的表,然后再刪除被參照的主鍵所在表。創建表時必須先建立被參照的主鍵所在表,然后建立外鍵所在表。
第五章
1.查詢全體學生的詳細記錄
Select Sno,Sname,Ssex,Sage,Sdept from Student
等價於 Select * from Student
2.查詢全體學生的姓名及出生年份
Student表中只記錄了學生的年齡,沒有記錄學生的出生年份,但我們可以經過計算得到出生年份,即用當前年減去年齡,得到出生年份。
Select Sname,2015-Sage from Student
3.含字符串常量的列
含字符串常量的列:查詢全體學生的姓名和出生年份,並在出生年份列前加入一個列,此列的每行數據均為“出生年份”常量值。
Select Sname,'出生年份',2015-Sage from Student
備注:經過計算的列、常量列的顯示結果都沒有列名,可以用表達式【AS】列別名的方式起列名。
4.去掉查詢語句的重復行
Select distinct Sno from SC
5.查詢計算機系全體學生的姓名
Select Sname from Student where Sdept='計算機系'
6.查詢所有年齡在20歲以下的學生姓名及年齡
Select sname,Sage from Student where Sage<20
7.查詢考試成績有不及格課程的學生的學號
Select distinct Sno from SC where Grade<60
8.查詢年齡在20~23歲的學生的姓名、所在系和年齡
Select Sname,Sdept,Sage from Student where sage between 20 and 23
此句等價於
Select Sname,Sdept,Sage from Student where Sage>=20 and Sage<=23
9.IN運算符的含義
IN運算符的含義為:當列中的值與集合中的某個常量值相等時,結果為true,表明此記錄為符合查詢條件的記錄。
NOT IN運算符的含義正好相反:當列中的值與集合中的某個常量值相等時,結果為false,表明此記錄為不符合查詢條件的記錄。
10.查詢信息管理系、通信工程系和計算機系學生的姓名和性別
Select Sname,Ssex from Student where Sdept=('信息管理系','通信工程系',‘計算機系’)
此句等價於:Select Sname,Ssex from Student where Sdept='信息管理系' OR Sdept='通信工程系'OR Sdept='計算機系'
11.查詢信息管理系、通信工程系和計算機系三個系之外的其他系學生的姓名和性別
Select Sname,Ssex from Student where Sdept NOT IN('信息管理系','通信工程系',‘計算機系’)
此句等價於:Select Sname,Ssex from Student where Sdept!='信息管理系' AND Sdept!='通信工程系'AND Sdept!='計算機系'
12.匹配串中可以包含如下4種通配符
_下畫線:匹配任意一個字符 %百分號:匹配0到多個字符【】:匹配【】中的任意一個字符。 【^】:不匹配【】中的任意一個字符。
13.查詢姓“張”的學生的詳細信息
Select * from Student where Sname like '張%'
14.查詢姓“張”、姓“李”和姓“劉”的學生的詳細信息
Select * from Student where Sname like '[張李劉]%'
15.查詢名字的第二個字為“小”或“大”的學生的姓名和學號
Select Sname,Sno from Student where Sname like '_[小大]%'
16.查詢所有不姓“劉”的學生姓名
Select Sname from Student where Sname NOT LIKE '劉%'
17.在Student表中查詢學號的最后一位不是2、3、5的學生的詳細信息
Select Sname from Student where Sno like '%[^235]'
18."ESCAPE"轉義字符
"ESCAPE"轉義字符是任何一個有效的字符,匹配串中也包含這個字符,表明位於該字符后面的那個字符將被視為普通字符,而不是通配符。
例如:為查找field1字段中包含字符串“30%”的記錄,可在where子句中指定:
Where field1 like '%30!%%' escape '!’
又如,為查找field1字段中包含下畫線(_)的記錄,可在where子句中指定:
Where field1 like '%!_%' escape '!'
19.判斷某個值是否為NULL
由於空值是不確定的值,因此判斷某個值是否為NULL,不能使用比較運算符,只能使用專門的判斷NULL值的子句來完成。而且,NULL不能與確定的值進行比較。
20.查詢沒有考試的學生的學號和相應的課程號
select sno,cno from sc
where grade is null
21.查詢所有已經考試了的學生的學號、課程號和考試成績
select sno , cno , grade from sc
where grade is not null
22.查詢計算機系年齡20歲以下的學生的姓名
select sname from student
where sdept = '計算機系' and sage <20
23.查詢計算機系和信息管理系學生中年齡在18~20的學生的 、姓名、所在系和年齡
select sno,sname,sdept,sage from student
where (sdept ='計算機系' or sdept = '信息管理系')
and sage between 18 and 20
注意:or運算符的優先級小於and,要改變運算的順序,可以通過加括號的方式來實現。
查詢語句也可以寫成 where sdept in ('計算機系','信息管理系')
24.排序
ASC表示按列值進行升序排序,DESC表示按列 值進行降序排序。默認排序方式ASC。
25.將學生按年齡升序排序
select * from student order by sage
查詢選修了“C002”課程的學生的學號及成績,查詢結果按成績降序排列.
select sno,grade from sc
where cno ='C002'
order by grade desc
查詢全體學生的信息,查詢結果按所在系的系名升序排列,同一個系的學生按年齡降序排列.
select * from student
order by sdept ASC,sage DESC
26.統計表中元組的個數
count(*):統計表中元組的個數. 除count(*)之外,其他函數在計算過程中均忽略null值。
27.統計學生總人數
select count(*) from student
統計選了課程的學生人數
select count(distinct sno) from sc
28.統計學號為“0811101”的學生的考試總成績
select sum(grade) from sc where sno='0811101'
統計“0831103”學生的考試平均成績.
只計算有成績的考試平均成績
select avg(grade) from sc where sno = '0831103'
29.查詢“C001”課程考試成績的最高分和最低分
select max(grade) 最高分,min(grade) 最低分 from sc where cno='C001'
30.統計每門課程 的選課人數,列出課程號和選課人數
select cno as 課程號,count(sno) as 選課人數 from sc group by cno
該語句首先對sc表中的數據按cno值進行分組,所有具有相同cno值的元組歸為一組,然后再對每一組使用count函數進行計算,求出每組的學生人數
31.統計每個學生 的選課門數和平均成績
select sno 學號,count(*) 選課門數,avg(grade) 平均成績 from sc group by sno
注意:group by 字句中的分組依據列必須是表中存在的列名,不能使用as子句指定的列別名。例如不能寫成group by 學號
32.統計每個系的學生人數和平均年齡
select sdept,count(*) as 學生人數,avg(sage) as 平均年齡 from student group by sdept
33.統計每個系的女生人數
select sdept, count(*) 女生人數 from student where ssex='女' group by sdept
34.按多個列分組
按多個列分組.統計每個系的男生人數和女生人數以及男生的最大年齡和女生的最大年齡。結果按系名升序排列.
分析:這個查詢首先應該按“所在系”進行分組,然后再每個系組中再按“性別”分組,而將每個系每個性別的學生聚集到一個組中,最后再對最終的分組結果進行統計.
注意:當有多個分組依據列時,統計是以最小組為單位進行的.
select sdept,ssex,count(*)人數,max(sage) 最大年齡 from student group by sdept,ssex order by sdept
35.HAVING子句
HAVING子句用於對分組后的統計結果再進行篩選,它的功能有點像WHERE子句,但它用於組,而不是單個記錄. 在HAVING子句中可以使用聚合函數,但在WHERE子句中則不能.
查詢選課門數超過3門的學生的學號和選課門數
select sno,count(*) 選課門數 from sc group by sno having count(*)>3
分析:此語句的處理過程為 先執行group by 子句對sc表數據按sno 進行分組統計出每個學生的選課門數,然后再用聚合函數count對每一組進行統計,最后篩選出統計結果大於3的組.
36.查詢計算機系和信息管理系每個系的學生人數
select sdept,count (*) from student where sdept in ('計算機系','信息管理系')
group by sdept
37.查詢每個系年齡小於等於20的學生人數
select sdept,count (*) from student where sage <=20 group by sdept
38.查詢每個學生及其選課的信息
由於學生信息存放在student表中,學生選課信息存放在sc表中,因此這個查詢涉及兩個表,這兩個表之間進行連接的條件是兩個表中的sno相等.
select * from student inner join sc on student.sno=sc.sno
sno列有兩個:一個來自student表,一個來自sc表,這兩個列的值完全相同(因為這里的連接條件是student.sno=sc.sno).使用多表連接查詢語句時一般將這些重復的列去掉,方法是在select子句中直接寫所需要的列名,而不是寫“*”。另外,由於進行多表連接后,在連接生成的表中可能存在列名相同的列,因此,為了明確需要的事哪個列,可以在列名前添加表名前綴限制.
去掉例40中的重復列
select student.sno,sname,ssex,sage,sdept,cno,grade from student join sc on student.sno=sc.sno
39.查詢計算機系學生的選課情況,列出學生的名字、所選課程的課程號和考試成績
select sname,cno,grade from student join sc on student.sno=sc.sno where sdept='計算機系'
40.自連接查詢中要求必須為表指定別名
select sname,cno,grade from student as s join sc on s.sno=sc.sno where sdept='計算機系'
注意:當為表指定了別名后,在查詢語句中的其他地方,所有用到該表名的地方都必須使用別名,不能再使用原表名.
每連接一張表,就需使用一個join子句
select sname,cname,grade from student s join sc on s.sno=sc.sno join course c on c.cno=sc.cno where sdept ='信息管理系' and cname='計算機文化學'
41.查詢所有選了vb課程的 學生姓名和所在系
select sname,sdept from student s
join sc on s.sno=sc.sno
join course c on c.cno=sc.cno
where cname='vb'
42.有分組統計的多表連接查詢。統計每個系的學生的考試平均成績
select sdept,avg(grade) as averagegrade from student s join sc on s.sno=sc.sno group by sdept
43.有分組和行選擇條件的多表連接查詢 。統計計算機系學生中每門課程的選課人數、平均成績、最高成績和最低成績
select cno,count(*) as total,avg(grade) as avggrade,max(grade) as maxgrade,min(grade) as mingrade from student s join sc on s.sno=sc.sno where sdept = '計算機系' group by cno
44.自連接是一種特殊的內連接,是指相互連接的表在物理上為同一張表,但在其邏輯上將其看成是兩張表
要讓物理上的一張表在邏輯上成為兩張表,必須通過為表起別名的方法
from 表1 as t1 join 表1 as t2 on 表1.列名=表2.列名
45.查詢與劉晨在同一個系學習的學生姓名和所在系
select s2.sname,s2.sdept
from student s1 join student s2
on s1.sdept=s2.sdept --是同一個系的學生
where s1.sname='劉晨 ' --s1表作為查詢條件表
and s2.sname!='劉晨' --s2表作為結果表,並從中去掉“劉晨”本人
46.查詢與“數據結構”課程在同一個學期開設的課程的課程名和開學學期
select c1.cname,c1.semester --c1作為查詢結果表
from course c1 join course c2
on c1.semester=c2.semester --是同一學期開設的課程
where c2.cname='數據結構' --c2表作為查詢條件表
47.外連接是只限制一張表中的數據必須滿足連接條件,而另一張表中的數據不必滿足連接條件.外連接分為左外連接和右外連接兩種
左外連接的含義是限制表2中的數據必須滿足連接條件,而不管表1中的數據是否滿足連接條件,均輸出表1中的內容;右外連接的含義是限制表1中的數據必須滿足連接條件,而不管表2中的數據是否滿足連接條件,均輸出表2中的內容.
48.查詢全體學生的選課情況,包括選了課的學生和沒有選課的學生
這個查詢需要輸出全體學生(student表中的全部數據)的信息,而不管這個學生是否選了課程(若沒選課,則在sc表中將沒有該學生的學號,即這些學生將不能滿足連接條件:student.sno=sc.sno)
selecct s.sno,sname,cno,grade
from student s
left outer join sc
on s.sno=sc.sno
注意:在連接結果中,將一個表中不滿足連接條件的數據構成的元組中的來自其他表的列均置成null
此查詢也可以用右外連接實現
select s.sno,sname,cno,grade
from sc right outer join student s
on s.sno=sc.sno
49.查詢沒有人選的課程的課程名
分析:如果某門課程沒有人選,則必定在course表中有,但在sc表中沒出現的課程,即進行外連接時,沒有人選的課程對應在sc表中相應的sno,cno或grade列上必定是空值,因此查詢時只要在連接后的結果中選出sc表中sno為mull或者cno為mull的記錄即可.
select cname from course c left join sc
on c.cno=sc.cno
where sc.cno is null
50.查詢計算機系沒有選課的學生,列出學生的姓名和性別
select sname,ssex
from student s left join sc on s.sno=sc.sno
where sdept='計算機系'
and sc.sno is null
51.統計計算機系每個學生的選課門數,包括沒有選課的學生
select s.sno as 學號,count(sc.cno) as 選課門數
from student s left join sc on s.sno=sc.sno
where sdept='計算機系'
group by s.sno
52.查詢信息管理系選課門數少於3門的學生的學號和選課門數,包括沒選課的學生.查詢結果按選課門數遞增排序
select s.sno as 學號,count(sc.cno) as 選課門數
from student s left join sc on s.sno=sc.sno
where sdept='信息管理系'
group by s.sno
having count(sc.cno)<3
order by count(sc.cno) asc
53.top子句寫在select單詞的后邊(如果有distinct,則在distinct單詞后),查詢列表的前邊
查詢年齡最大的三個學生的姓名、年齡及其所在系
select top 3 sname,sage,sdept
from student
order by sage desc
若要包括年齡並列第3名的所有學生,則此句可寫成
select top 3 with ties sname,sage,sdept
from student
order by sage desc
注意:如果在top子句中使用了with ties謂詞,則要求必須使用order by子句對查詢結果進行排序,否則會出現語法錯誤
54.查詢vb考試成績最高的前三名學生的姓名、所在系和vb考試成績
select top 3 with ties sname,sdept,grade
from student s join sc on s.sno=sc.sno
join course c on c.cno=sc.cno
where cname='vb'
order by grade desc
55.查詢選課人數最少的兩門課程(不包括沒有人選的課程),列出課程號和選課人數
select top 2 with ties cno,count(*) 選課人數
from sc
group by cno
order by count(cno) asc
56.查詢計算機系選課門數超過兩門的學生中考試平均成績最高的前兩名(包括並列情況)學生的學號、選課門數和平均成績
select top 2 with ties s.sno,count (*) 選課門數,avg(grade) 平均成績
from student s join sc on s.sno=sc.sno
where sdept='計算機系'
group by s.sno
having count(*)>2
order by avg(grade) desc
57.查詢選了vb課程的學生的學號、姓名、所在系和成績,計算機系顯示cs ,信息管理系顯示im,通信工程系com
select s.sno 學號,sname 姓名,
case sdept
when '計算機系' then 'cs'
when '信息管理系' then 'im'
when '通信工程系' then 'com'
end as 所在系,grade 成績
from student s join sc on s.sno=sc.sno
join course c on c.cno=sc.cno
where cname='vb'
58.查詢計算機系學生的學號、姓名、性別和年齡,並將查詢結果保存到新表student_cs中
select sno,sname,ssex,sage
into student_cs
from student where sdept = '計算機系'
59.查詢與劉晨在同一系學習的學生
select sno,sname,sdept from student --外層查詢
where sdept in(select sdept from student where sname='劉晨') --子查詢
60.使用子查詢實現:查詢考試成績大於90分的學生的學號和姓名
select sno,sname from student
where sno in(select sno from sc where grade > 90)
61.查詢選了"c004"號課程且成績高於此課程平均成績的學生的學號和該門課程成績
select sno,grade from sc
where cno='c004' and grade<(
select avg(grade) from sc where cno='c004')
62.exists的含義是:當子查詢中有滿足條件的數據時,返回真值,否則返回假值
not exists的含義是:當子查詢中有滿足條件的數據時,返回假值,否則返回真值
查詢沒選“c001”號課程的學生的姓名和所在系
a.在子查詢中否定
select sname,sdept from student
where exists(
select * from sc
where sno = student.sno
and cno!='c001')
b.在外層查詢中否定
select sname,sdept from student
where not exists(
select * from sc
where sno = student.sno
and cno = 'c001')
63.將一個新生插入student表中,其學號為0821105,姓名為陳冬,性別為男,年齡為18歲,信息管理系學生
insert into student values('0821105','陳冬,'男',18,'信息管理系')
在sc表中插入一條新紀錄,學號為“0821105”,選修的課程號為“c001”,成績暫缺
insert into sc(sno,cno) values('0821105','c001')
注意:由於提供的常量值個數與表中的列個數不一致,因此在插入時必須列出列名.而且,sc表中的grade列必須允許為null
64.創建一個新表,然后將計算機系每個學生的姓名、選的課程名和考試成績插入到此表中
(1)創建表
create table cs_student(
sname varchar( 20),
cname varchar(40),
grade tinyint)
(2)插入數據
insert into cs_student
select sname,cname,grade from student s
join sc on s.sno=sc.sno
join course c on c.cno=sc.cno
where sdept='計算機系'
65.無條件更新
將所有學生的年齡加1
update student set sage=sage+1
66.有條件更新
(1)基於本表條件的更新
將“0811104”號學生的年齡改為18歲
update student set sage = 18
where sno='0811104'
(2)基於其他表條件的更新
將計算機系全體學生的成績加5分
-用子查詢實現
update sc set grade=grade+5
where sno in
(select sno from student where sdept='計算機系')
-用多表連接實現
update sc set grade=grade+5
from sc join student on sc.sno=student.sno
where sdept='計算機系'
67.修改全體學生的vb考試成績:對通信工程系學生,成績加10分。對信息管理系學生,成績加5分。對其他系學生,成績不變
update sc set grade =grade+
case sdept
when '通信工程系' then 10
when '信息管理系' then 5
else 0
end
from student s join sc on s.sno=sc.sno
join course c on c.cno=sc.cno
where cname='vb'
68.無條件刪除
刪除所有學生的選課記錄
delete from sc --sc成空表
有條件刪除
(1)基於本表條件的刪除
刪除所有不及格學生的修課記錄
delete from sc where grade < 60
(2)基於其他表條件的刪除
刪除計算機系不及格學生的修課記錄
-用子查詢 實現
delete from sc
where grade<60 and sno in(
select sno from student
where sdept ='計算機系')
-用多表連接
delete from sc
from sc join student on sc.sno=student.sno
where sdept='計算機系' and grade<60