版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第3章關(guān)系數(shù)據(jù)庫(kù)與SQL語(yǔ)言
3.1關(guān)系數(shù)據(jù)庫(kù)的結(jié)構(gòu)3.2關(guān)系代數(shù)3.3擴(kuò)展的關(guān)系代數(shù)3.4數(shù)據(jù)庫(kù)的修改操作3.5SQL3.6查詢優(yōu)化技術(shù)習(xí)題關(guān)系模型是目前最重要的一種數(shù)據(jù)模型。關(guān)系數(shù)據(jù)庫(kù)系統(tǒng)是以關(guān)系模型作為數(shù)據(jù)組織、管理方式的數(shù)據(jù)庫(kù)管理系統(tǒng)。1970年美國(guó)IBM公司SanJose研究室的研究員E.F.Codd首次提出了關(guān)系模型,開(kāi)創(chuàng)了數(shù)據(jù)庫(kù)關(guān)系方法和關(guān)系代數(shù)理論的研究領(lǐng)域,為關(guān)系數(shù)據(jù)庫(kù)技術(shù)奠定了理論基礎(chǔ)。
20世紀(jì)80年代以來(lái),計(jì)算機(jī)軟件廠商紛紛推出各自的數(shù)據(jù)庫(kù)管理系統(tǒng),其中涌現(xiàn)出許多性能良好的商用關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)(簡(jiǎn)稱RDBMS),如著名的SQLServer、DB2、Oracle、Ingres、Sybase和Informix等關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)。隨著關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)的發(fā)展和成熟,數(shù)據(jù)庫(kù)的應(yīng)用領(lǐng)域迅速擴(kuò)大。可以說(shuō),目前所有主流的數(shù)據(jù)庫(kù)應(yīng)用領(lǐng)域都離不開(kāi)關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng),而非關(guān)系模型的數(shù)據(jù)庫(kù)管理系統(tǒng)的產(chǎn)品也大都支持關(guān)系模型或擴(kuò)展關(guān)系模型。本章先學(xué)習(xí)關(guān)系模型的理論基礎(chǔ),了解關(guān)系模型的數(shù)據(jù)表示方法;然后介紹關(guān)系數(shù)據(jù)庫(kù)查詢語(yǔ)言。3.1關(guān)系數(shù)據(jù)庫(kù)的結(jié)構(gòu)在關(guān)系模型中,無(wú)論是實(shí)體還是實(shí)體之間的聯(lián)系均由單一的結(jié)構(gòu)類型——關(guān)系(表)來(lái)表示。關(guān)系模型是建立在關(guān)系代數(shù)基礎(chǔ)上的面向集合操作的數(shù)據(jù)模型,這里將從集合論角度給出關(guān)系模型的形式化定義。關(guān)系數(shù)據(jù)庫(kù)是若干表的集合,每個(gè)表有唯一的名字。表的每一行數(shù)據(jù)代表現(xiàn)實(shí)世界的一個(gè)實(shí)體或者一個(gè)關(guān)聯(lián)。一個(gè)表就是一個(gè)實(shí)體集或一個(gè)關(guān)聯(lián)集。3.1.1基本關(guān)系結(jié)構(gòu)首先通過(guò)一個(gè)超市銷售系統(tǒng)的實(shí)例介紹關(guān)系模型。表3.1給出了超市銷售系統(tǒng)的“營(yíng)業(yè)員”表,其中存放所有營(yíng)業(yè)員的信息。該表有3列:工號(hào)、姓名和出生年月,每一列稱為一個(gè)屬性。每個(gè)屬性對(duì)應(yīng)一個(gè)定義取值范圍的集合,稱為該屬性的域。例如,屬性“姓名”的域是長(zhǎng)度為4個(gè)漢字的字符串的集合。如果用D1表示營(yíng)業(yè)員工號(hào)的域,用D2表示營(yíng)業(yè)員姓名的域,用D3表示營(yíng)業(yè)員出生年月的域。“營(yíng)業(yè)員”表的每一行都是一個(gè)三元組(v1,v2,v3),其中v1是營(yíng)業(yè)員工號(hào)(v1在域D1中),v2是營(yíng)業(yè)員姓名(v2在域D2中),v3是營(yíng)業(yè)員出生年月(v3在域D3中)。通常,一個(gè)超市銷售系統(tǒng)的“營(yíng)業(yè)員”表是集合D1×D2×D3的一個(gè)有實(shí)際意義的子集。一般地說(shuō),有n個(gè)屬性的表是D1×D2×…×Dn-1×?Dn的一個(gè)子集,D1×?D2×…×Dn-1×Dn在數(shù)學(xué)上定義為域D1、D2、…、Dn-1、Dn上的笛卡爾積。關(guān)系就是定義在一系列域上的笛卡爾積的子集??梢?jiàn),表實(shí)際上就是關(guān)系,因此可以用數(shù)學(xué)名詞關(guān)系和元組來(lái)代替表和行?!盃I(yíng)業(yè)員”表也可以稱為“營(yíng)業(yè)員”關(guān)系。元組變量就是代表元組的變量,即存放關(guān)系的一個(gè)元組的變量。表3.1“營(yíng)業(yè)員”表如表3.1所示,“營(yíng)業(yè)員”關(guān)系中共有8個(gè)元組。設(shè)元組變量t指向關(guān)系中的第一個(gè)元組,那么t?[工號(hào)]?表示t在“工號(hào)”屬性上的值。當(dāng)前t?[工號(hào)]?的值是“001”,t?[姓名]?的值是“金文”。也可以用t?[1]?來(lái)表示元組t的第一個(gè)屬性(工號(hào))上的值,t?[2]?表示元組t的第二個(gè)屬性上的值,等等。因?yàn)殛P(guān)系是元組的集合,所以可以用數(shù)學(xué)上tR表示元組t在關(guān)系R中。由于關(guān)系是元組的集合,所以元組在關(guān)系中出現(xiàn)的順序是無(wú)關(guān)緊要的。表3.2和表3.1所表示的關(guān)系是一樣的,因?yàn)樗鼈兪前嗤M的集。表3.2具有無(wú)序元組的“營(yíng)業(yè)員”關(guān)系對(duì)于所有關(guān)系R,要求它的每個(gè)屬性都是原子的。如果某個(gè)屬性是不可分的最小單元,則稱其是原子的。如果“出生年月”屬性定義為長(zhǎng)度為6的字符串,那么其就是原子的;相反,如果“出生年月”定義為“年”+“月”,那么其就不是原子的。關(guān)系模型允許幾個(gè)屬性屬于相同的域。注意:空值NULL是一個(gè)特殊的值,表示值未知或不存在,其存在于所有的域??罩禃?huì)給數(shù)據(jù)庫(kù)訪問(wèn)和更新帶來(lái)很多困難,所以要盡量避免使用空值。3.1.2數(shù)據(jù)庫(kù)模式數(shù)據(jù)庫(kù)模式(DataBaseSchema)是數(shù)據(jù)庫(kù)的邏輯設(shè)計(jì),是由數(shù)據(jù)庫(kù)所包含的所有數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)、其間關(guān)系和約束條件組成的框架。數(shù)據(jù)庫(kù)實(shí)例(DataBaseInstance)是給定時(shí)刻數(shù)據(jù)庫(kù)中數(shù)據(jù)的一個(gè)快照,即在給定時(shí)刻在某種數(shù)據(jù)庫(kù)模式下的全體數(shù)據(jù)的集合。因而數(shù)據(jù)庫(kù)設(shè)計(jì)就是數(shù)據(jù)庫(kù)模式的設(shè)計(jì)。關(guān)系數(shù)據(jù)庫(kù)模式是基于關(guān)系模式的。關(guān)系模式(RelationSchema)是型,關(guān)系是值,關(guān)系模式是對(duì)關(guān)系的描述,它包括屬性序列、屬性來(lái)自的域、屬性與域之間的映像關(guān)系、元組語(yǔ)義描述以及完整性約束條件、屬性間的數(shù)據(jù)依賴關(guān)系的集合。關(guān)系模式可以形式化地表示為
R(U,D,DOM,F(xiàn))其中R是關(guān)系名,U是組成該關(guān)系的屬性的集合,D是屬性組U中屬性取值的域,DOM是屬性到域的映像規(guī)則的集合,F(xiàn)是屬性間的數(shù)據(jù)依賴關(guān)系的集合。關(guān)系模式定義的四元組中,D、DOM、F三個(gè)部分在關(guān)系運(yùn)算理論研究中非常重要,其作用將在后續(xù)各章體現(xiàn),但在本章的論述中用處不多,所以本章將關(guān)系模式簡(jiǎn)記為R(U)或R(A1,A2,…,An),其中R是關(guān)系名,A1,A2,…,A是屬性名,這里有U?=?(A1,A2,…,A)。這里n稱為關(guān)系的元數(shù),具有n個(gè)屬性的關(guān)系稱為n元關(guān)系。例如,表3.3給出的“銷售”關(guān)系的關(guān)系模式可以記為:銷售(工號(hào),商品代碼,銷售數(shù)量),從中可以看出關(guān)系模式是對(duì)關(guān)系的描述,是靜態(tài)的、穩(wěn)定的。關(guān)系是關(guān)系模式在某一時(shí)刻的狀態(tài)或內(nèi)容值,是動(dòng)態(tài)、隨時(shí)間不斷變化的。表3.3?“銷售”關(guān)系關(guān)系實(shí)例的概念對(duì)應(yīng)于程序設(shè)計(jì)語(yǔ)言中變量的值的概念,給定變量的值隨著時(shí)間的推移發(fā)生變化,當(dāng)關(guān)系被更新時(shí),關(guān)系實(shí)例的內(nèi)容也隨時(shí)間發(fā)生了變化。通常簡(jiǎn)單地用“關(guān)系”指代“關(guān)系實(shí)例”。如表3.3的所有數(shù)據(jù)展示了關(guān)系模式“銷售(工號(hào),商品代碼,銷售數(shù)量)”在某一時(shí)刻的一個(gè)關(guān)系實(shí)例。下面介紹幾個(gè)術(shù)語(yǔ)。
(1)候選碼:如果關(guān)系中的某一屬性組的值能唯一地標(biāo)識(shí)一個(gè)元組,則稱該屬性組為侯選碼。候選碼的諸屬性稱為主屬性(PrimeAttribute),不包含在任何侯選碼中的屬性稱為非主屬性(Non-PrimeAttribute)。在簡(jiǎn)單的情況下,候選碼只包含一個(gè)屬性。
(2)全碼(All-key):關(guān)系模式的所有屬性組都是這個(gè)關(guān)系模式的候選碼,稱為全碼(All-key)。若一個(gè)關(guān)系有多個(gè)候選碼,則選定其中一個(gè)為主碼。
(3)外碼、參照關(guān)系、被參照關(guān)系:設(shè)F是基本關(guān)系R的一個(gè)或一組屬性,但不是關(guān)系R的碼。如果F與基本關(guān)系S的主碼KS相對(duì)應(yīng),則稱F是基本關(guān)系R的外碼,基本關(guān)系R稱為參照關(guān)系(ReferencingRelation),基本關(guān)系S稱為被參照關(guān)系(ReferencedRelation)或目標(biāo)關(guān)系(TargetRelation)。關(guān)系R和S不一定是不同的關(guān)系,目標(biāo)關(guān)系S的主碼KS和參照關(guān)系的外碼F必須定義在同一個(gè)(或一組)域上,外碼并不一定要與相應(yīng)的主碼同名。當(dāng)外碼與相應(yīng)的主碼屬于不同關(guān)系時(shí),往往取相同的名字,以便于識(shí)別。
(4)模式圖:表示一個(gè)含有主碼和外碼依賴的數(shù)據(jù)庫(kù)模式的圖。例如一個(gè)“銷售”數(shù)據(jù)庫(kù)的E-R圖如圖3.1所示,圖3.2展示了該“銷售”數(shù)據(jù)庫(kù)的模式圖。圖中,每一個(gè)關(guān)系用矩形來(lái)表示,矩形內(nèi)列出屬性,矩形上面是關(guān)系的名字。如果有主碼屬性,用一條橫線將主碼屬性分隔在方框上部。外碼依賴用從參照關(guān)系的外碼屬性到被參照關(guān)系的主碼屬性之間的一個(gè)箭頭來(lái)表示。圖3.1“銷售”數(shù)據(jù)庫(kù)的E-R圖圖3.2“銷售”數(shù)據(jù)庫(kù)的模式圖3.1.3查詢語(yǔ)言查詢語(yǔ)言(QueryLanguage)是用戶向數(shù)據(jù)庫(kù)請(qǐng)求以獲取信息的語(yǔ)言。這些語(yǔ)言通常比一般的程序設(shè)計(jì)語(yǔ)言層次更高。查詢語(yǔ)言可以分為過(guò)程化的和非過(guò)程化的。在過(guò)程語(yǔ)言中,用戶指導(dǎo)系統(tǒng)對(duì)數(shù)據(jù)庫(kù)執(zhí)行一系列操作以計(jì)算所需的結(jié)果。在非過(guò)程語(yǔ)言中,用戶只需描述所需信息,而不用給出獲取該信息的具體過(guò)程。大多數(shù)商用關(guān)系數(shù)據(jù)庫(kù)系統(tǒng)提供的查詢語(yǔ)言中既包含過(guò)程化的部分,又包含非過(guò)程化的部分。常見(jiàn)的查詢語(yǔ)言有SQL、QBE、Datalog等。3.1.4關(guān)系數(shù)據(jù)模型的優(yōu)缺點(diǎn)關(guān)系型數(shù)據(jù)庫(kù)最大的特點(diǎn)在于它將每個(gè)具有相同屬性的數(shù)據(jù)獨(dú)立地存儲(chǔ)在一個(gè)表中。對(duì)任何一個(gè)表而言,用戶可以新增、刪除、修改表中任何一行的數(shù)據(jù),而不會(huì)影響表中其他的數(shù)據(jù)。它解決了層次型數(shù)據(jù)體橫向關(guān)聯(lián)不足的缺點(diǎn),也避免了網(wǎng)狀數(shù)據(jù)庫(kù)關(guān)聯(lián)過(guò)于復(fù)雜的問(wèn)題。關(guān)系數(shù)據(jù)模型具有下列優(yōu)點(diǎn):
(1)關(guān)系模型與非關(guān)系模型不同,它是建立在嚴(yán)格數(shù)學(xué)概念的基礎(chǔ)上的。
(2)關(guān)系模型的概念單一。無(wú)論實(shí)體還是實(shí)體之間的關(guān)聯(lián)都用關(guān)系表示。數(shù)據(jù)的檢索結(jié)果也是關(guān)系(即表),因此,其數(shù)據(jù)結(jié)構(gòu)簡(jiǎn)單、清晰,用戶易懂易用。
(3)關(guān)系模型的存取路徑對(duì)用戶透明,從而具有更高的數(shù)據(jù)獨(dú)立性和更好的安全保密性,也簡(jiǎn)化了程序員的工作和數(shù)據(jù)庫(kù)開(kāi)發(fā)的工作。關(guān)系數(shù)據(jù)模型誕生以后發(fā)展迅速,深受用戶的喜愛(ài)。當(dāng)然,關(guān)系數(shù)據(jù)模型也有缺點(diǎn),其最主要的缺點(diǎn)是,由于存取路徑對(duì)用戶透明,查詢效率往往不如非關(guān)系數(shù)據(jù)模型。因此為了提高性能,必須對(duì)用戶的查詢請(qǐng)求進(jìn)行優(yōu)化,這增加了開(kāi)發(fā)數(shù)據(jù)庫(kù)管理系統(tǒng)的難度。3.2關(guān)系代數(shù)任何一種運(yùn)算都是將一定的運(yùn)算符作用于一定的運(yùn)算對(duì)象上,得到預(yù)期的運(yùn)算結(jié)果。所以運(yùn)算對(duì)象、運(yùn)算符、運(yùn)算結(jié)果是運(yùn)算的三大要素。關(guān)系代數(shù)的運(yùn)算對(duì)象是關(guān)系,運(yùn)算結(jié)果亦為關(guān)系。關(guān)系代數(shù)是以集合代數(shù)為基礎(chǔ)發(fā)展起來(lái)的,它是以關(guān)系為運(yùn)算對(duì)象的一組高級(jí)運(yùn)算的集合。它包括一個(gè)運(yùn)算的集合,這些運(yùn)算以一個(gè)或兩個(gè)關(guān)系為輸入,產(chǎn)生一個(gè)新的關(guān)系作為結(jié)果。關(guān)系代數(shù)為關(guān)系模型操作提供了一個(gè)形式化基礎(chǔ),因而關(guān)系代數(shù)被看做是在關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)(RDBMS)中實(shí)現(xiàn)和優(yōu)化查詢的基礎(chǔ)。RDBMS的SQL標(biāo)準(zhǔn)查詢語(yǔ)言中結(jié)合了關(guān)系代數(shù)中的一些概念。3.2.1基本運(yùn)算在關(guān)系代數(shù)中,選擇、投影和更名運(yùn)算都是對(duì)單一關(guān)系進(jìn)行運(yùn)算的關(guān)系操作,稱為一元運(yùn)算。
1.選擇運(yùn)算選擇(Selection)運(yùn)算是根據(jù)某些條件對(duì)關(guān)系進(jìn)行水平查詢,提取出符合條件的元組。查詢的條件用命題公式F表示;F是選擇謂詞表達(dá)式,其中的運(yùn)算對(duì)象是常量(用引號(hào)括起來(lái))或元組分量(屬性名或列的序號(hào)),其中的運(yùn)算符有算術(shù)比較運(yùn)算符(<,≤,>,≥,=,≠,這些符號(hào)統(tǒng)稱為θ符)和邏輯運(yùn)算符(∧,∨,?);這里?{<,≤,>,≥}?適用于域是有序值的屬性,如數(shù)值域或日期域。如果屬性域是無(wú)序值的集合,那么只能使用集合?{=,≠}。用σ表示選擇,將條件表達(dá)式寫為σ的下標(biāo),那么關(guān)系R關(guān)于選擇謂詞F的選擇操作表示為σF(R),其形式化的定義如下:σF(R)?=?{t│t∈R∧F(t)?=?true}
例3.1“商品”關(guān)系如表3.4所示,若要在其中選擇生產(chǎn)商為“四川長(zhǎng)虹電器有限公司”的元組。用選擇運(yùn)算可以表示為σ生產(chǎn)商=“四川長(zhǎng)虹電器有限公司”
(商品)表3.4“商品”關(guān)系本例選擇操作所產(chǎn)生的結(jié)果關(guān)系如表3.5所示。如果進(jìn)一步“查找銷售價(jià)格大于1500元的所有元組”,則可以表示為σ銷售價(jià)格>1500(商品)。通常允許在選擇謂詞中進(jìn)行比較,使用的是=,≠,<,≤,>和≥,還可以用連詞and(∧),or(∨)和not(?)將多個(gè)謂詞合并為一個(gè)較大的謂詞。如果查找“銷售價(jià)格大于1500,并由四川長(zhǎng)虹電器公司生產(chǎn)的商品”,則可以表示為σ生產(chǎn)商=“四川長(zhǎng)虹電器有限公司”∧銷售價(jià)格>1500(商品)表3.5σ生產(chǎn)商=“四川長(zhǎng)虹電器有限公司”
(商品)的結(jié)果
2.投影運(yùn)算投影(Projection)是對(duì)一個(gè)關(guān)系進(jìn)行垂直分割,消去某列,并重新安排列的順序,再刪去重復(fù)元組。投影用π表示,將希望在操作結(jié)果中出現(xiàn)的屬性組作為π的下標(biāo),作為參數(shù)的關(guān)系放在π后的括號(hào)中。設(shè)有k元關(guān)系R(A1,A2,…,Ak),R在其分量(m≤k,i1,…,im為1到k之間的整數(shù))上的投影用表示,它是從R中選擇若干屬性列組成的一個(gè)m元關(guān)系。其形式化定義如下:
例3.2
列出“商品”關(guān)系中“所有商品代碼及銷售價(jià)格”可以表示為π商品代碼,銷售價(jià)格(商品)。投影操作所產(chǎn)生的結(jié)果關(guān)系如表3.6所示。表3.6商品代碼和銷售價(jià)格
3.并運(yùn)算(Union)設(shè)關(guān)系R和關(guān)系S具有相同的元數(shù)n(即兩個(gè)關(guān)系都有n個(gè)屬性),且相應(yīng)的屬性取自同一個(gè)域,則關(guān)系R和關(guān)系S的并是由屬于R或?qū)儆赟的元組組成的關(guān)系。其結(jié)果仍為n元關(guān)系。記為R∪S。其形式化定義如下:R∪S?=?{t│t?∈R∨t∈S}其中,t是元組變量,R和S的元數(shù)相同。兩個(gè)關(guān)系的并運(yùn)算是將兩個(gè)關(guān)系中的所有元組構(gòu)成一個(gè)新關(guān)系。并運(yùn)算要求兩個(gè)關(guān)系屬性的性質(zhì)必須一致而且并運(yùn)算的結(jié)果要消除重復(fù)的元組。要使并運(yùn)算R∪S有意義,需要以下兩個(gè)條件同時(shí)成立:
(1)關(guān)系R和S必須是同元的,即它們的屬性數(shù)目必須相同;
(2)對(duì)所有的t,R的第t個(gè)屬性的域必須和S的第t個(gè)屬性的域相同。
例3.3
查詢銷售了T002和T006商品的營(yíng)業(yè)員的工號(hào)。需要將銷售了T002和銷售了T006的員工集合并起來(lái)。具體可以表示為π工號(hào)(σ商品代碼=“T002”(銷售)∪σ商品代碼=“T006”(銷售))“銷售”關(guān)系,如前面的表3.3所示,則查詢所產(chǎn)生的結(jié)果關(guān)系如表3.7所示。表3.7例3.3查詢結(jié)果
4.差運(yùn)算設(shè)關(guān)系R和關(guān)系S具有相同的元數(shù)n,且相應(yīng)的屬性取自同一個(gè)域,則關(guān)系R和關(guān)系S的差由屬于R而不屬于S的所有元組組成。其結(jié)果仍為n元關(guān)系。記為R?-?S。其形式化定義如下:R?-?S?=?{t?|?t∈R∧t
S}
例3.4
查詢所有未銷售商品的營(yíng)業(yè)員的工號(hào)。該查詢可以用差運(yùn)算來(lái)表示:π工號(hào)(營(yíng)業(yè)員)?-?π工號(hào)(銷售)關(guān)系“營(yíng)業(yè)員”和“銷售”參見(jiàn)表3.1和表3.3,則查詢所產(chǎn)生的結(jié)果關(guān)系如表3.8所示。表3.8未銷售商品的營(yíng)業(yè)員
5.關(guān)系的笛卡兒積(CartesianProduct)設(shè)關(guān)系R和關(guān)系S的元數(shù)分別為r和s,定義關(guān)系R和關(guān)系S的笛卡兒積R?×?S是一個(gè)(r+s)元關(guān)系,所得關(guān)系的每個(gè)元組的前r個(gè)分量(屬性值)來(lái)自R的一個(gè)元組,后s個(gè)分量來(lái)自S的一個(gè)元組,記為R?×?S。其形式化定義如下:R?×?S?=?{trts?|?tr∈R∧ts∈S}若R有n個(gè)元組,S有m個(gè)元組,則R?×?S有n?×?m個(gè)元組,n?×?m稱為該笛卡兒積的基數(shù)。為了簡(jiǎn)化描述笛卡爾積的概念,需要構(gòu)造“銷售”關(guān)系的子關(guān)系,取名“銷售子關(guān)系”,該構(gòu)造的關(guān)系代數(shù)操作為σ工號(hào)=“003”∧工號(hào)=“004”(銷售),所得操作結(jié)果如表3.9所示。表3.9銷售子關(guān)系
例3.5求解“商品”關(guān)系和“銷售”子關(guān)系的笛卡兒積。關(guān)系“銷售”和“商品”的笛卡兒積的關(guān)系模式可以表示為
(銷售.工號(hào),銷售.商品代碼,銷售.銷售日期,銷售.銷售數(shù)量,商品.商品代碼,商品.商品名稱,商品.生產(chǎn)商,商品.銷售價(jià)格)用“.”分級(jí)的模式,可以區(qū)別“銷售.商品代碼”和“商品.商品代碼”。對(duì)只在兩個(gè)關(guān)系模式之一中出現(xiàn)的屬性,通常省略其關(guān)系名前綴,所以可以將上述的關(guān)系模式簡(jiǎn)寫為
(工號(hào),銷售.商品代碼,銷售日期,銷售數(shù)量,商品.商品代碼,商品名稱,生產(chǎn)商,銷售價(jià)格)參與笛卡兒積運(yùn)算的關(guān)系的名字必須不同?!吧唐贰标P(guān)系和“銷售”子關(guān)系的笛卡兒積如表3.10所示。表3.10“商品”關(guān)系和“銷售”子關(guān)系的笛卡兒積3.2.2擴(kuò)展運(yùn)算關(guān)系代數(shù)的基本運(yùn)算足以表達(dá)任何關(guān)系代數(shù)查詢。但是不能局限于基本運(yùn)算,因?yàn)槟承┏S貌樵儽磉_(dá)出來(lái)會(huì)顯得冗長(zhǎng),所以需要定義一些擴(kuò)展運(yùn)算,可以簡(jiǎn)化一些常用的查詢。
1.交運(yùn)算用“∩”表示關(guān)系交運(yùn)算。設(shè)關(guān)系R和關(guān)系S具有相同的元數(shù)n,且相應(yīng)的屬性取自同一個(gè)域。關(guān)系R和關(guān)系S的交記為R∩S,其結(jié)果仍為n元的關(guān)系,是由既屬于R又屬于S的元組成。其形式化定義如下:R∩S?=?{t│t∈R∧t∈S}其中,t是元組變量,R和S的元數(shù)相同。關(guān)系的交也可以用關(guān)系的差來(lái)表示,即:R∩S
=
R
-
(R
-
S)或R∩S
=
S
-
(S
-
R)
例3.6查詢既銷售了T002商品又銷售了T003商品的營(yíng)業(yè)員的工號(hào)。在“銷售”關(guān)系中分別求出銷售了T002和T003商品的銷售子關(guān)系,然后用交運(yùn)算求解。π工號(hào)(σ商品代碼=“T002”(銷售)∩σ商品代碼=“T003”(銷售))運(yùn)算產(chǎn)生的結(jié)果關(guān)系如表3.11所示。表3.11例3.6操作結(jié)果
2.自然連接運(yùn)算對(duì)有些要用到笛卡兒積的查詢進(jìn)行簡(jiǎn)化常常是必要的。自然連接運(yùn)算(Naturaljoin),可以將某些選擇和笛卡兒積運(yùn)算合并為一個(gè)運(yùn)算?!斑B接”用符號(hào)“??”來(lái)表示。自然連接是一種特殊的等值連接,它要求兩個(gè)關(guān)系中進(jìn)行比較的分量必須是相同的屬性組,并且要在結(jié)果中把重復(fù)的屬性去掉。自然連接運(yùn)算首先形成它的兩個(gè)關(guān)系的笛卡兒積,然后基于兩個(gè)關(guān)系模式中都出現(xiàn)的屬性上的相等性進(jìn)行選擇,最后還要去除重復(fù)屬性。盡管自然連接的定義很復(fù)雜,使用起來(lái)卻很方便。自然連接具體計(jì)算過(guò)程如下:
(1)計(jì)算R?×?S。
(2)設(shè)R和S的公共屬性是A1,…,Ak,挑選R?×?S中滿足R.A1?=?S.A1,…,R.Ak
=?S.Ak的那些元組。
(3)去掉S.A1,…,S.Ak這些列(保留R.A1,…,R.Ak列)。自然連接的形式化定義如下:
R???S?=?πR∪S其中R∪S表示由關(guān)系R和S的屬性構(gòu)成的集合。例3.7
查詢所有銷售人員的工號(hào)及銷售的商品代碼和銷售價(jià)格??梢杂米匀贿B接表示該查詢:π工號(hào),商品代碼,銷售價(jià)格(銷售???商品)“銷售”、“商品”關(guān)系,如前面的表3.3和表3.4所示。則查詢所產(chǎn)生的結(jié)果關(guān)系如表3.12所示。表3.12π工號(hào),商品代碼,銷售價(jià)格(銷售??商品)
3.除(Division)運(yùn)算
R、?S是兩個(gè)關(guān)系且S?R,R與S的除法是寫為R?÷?S的二元關(guān)系,其結(jié)果是模式R?-?S(結(jié)果關(guān)系的屬性僅僅取自于關(guān)系R的屬性)上的關(guān)系,并且結(jié)果關(guān)系中的元組與S中的元組的所有組合構(gòu)成的元組都存在于R中。除法的形式定義如下:
R÷S={t?[a1,…,an]?|?t∈R∧?s∈S((t[a1…,an]∪s)∈R)}其中a1,…,an是R的屬性名字的集合并且不屬于S的屬性集合,通常要求在S的屬性集合是R的屬性集合的子集,否則運(yùn)算的結(jié)果永遠(yuǎn)為空。
例3.8求表3.13所示“關(guān)系R”和表3.14所示“關(guān)系S”的除法。
R÷S除法產(chǎn)生的關(guān)系如表3.15所示。如果關(guān)系S包含了康佳集團(tuán)的的所有產(chǎn)品,則這個(gè)除法的結(jié)果精確地包含了銷售過(guò)康佳集團(tuán)所有產(chǎn)品的銷售人員。表3.13關(guān)系R
表3.14關(guān)系S表3.15關(guān)系R÷S3.3擴(kuò)展的關(guān)系代數(shù)在關(guān)系代數(shù)運(yùn)算的發(fā)展過(guò)程中,基本的關(guān)系代數(shù)具有一定的局限性,為了進(jìn)一步方便用戶,增強(qiáng)檢索功能,需要引進(jìn)擴(kuò)展的關(guān)系代數(shù)。這里主要包括廣義投影、聚集運(yùn)算、外連接等運(yùn)算。
3.3.1廣義投影廣義投影運(yùn)算通過(guò)允許在投影列表中使用代數(shù)函數(shù)來(lái)對(duì)投影進(jìn)行擴(kuò)展。投影操作是對(duì)一個(gè)關(guān)系進(jìn)行垂直分割,消去某些列,并重新安排列的順序,再刪去重復(fù)元組。其運(yùn)算形式定義如下:其中,E是任意關(guān)系代數(shù)表達(dá)式,而F1,F(xiàn)2,…,F(xiàn)n中的每一個(gè)都是涉及常量以及E的模式中屬性的算數(shù)表達(dá)式。特別地,算術(shù)表達(dá)式可以僅僅是個(gè)屬性或常量。在制作列中需要產(chǎn)生計(jì)算值的報(bào)表時(shí),這個(gè)操作可以作為一個(gè)幫助性的操作。
例3.9根據(jù)表3.1“營(yíng)業(yè)員”關(guān)系中的出生年份,通過(guò)當(dāng)前所在年份,計(jì)算出營(yíng)業(yè)員的年齡。其廣義投影運(yùn)算可以表示為π工號(hào),姓名,出生年份,(2009-出生年份)(營(yíng)業(yè)員)表達(dá)式“2009-出生年份”產(chǎn)生的屬性沒(méi)有名字,可以通過(guò)對(duì)廣義投影的結(jié)果重命名的方式給它一個(gè)名字。屬性更名可以與廣義投影相結(jié)合,具體表示為π工號(hào),姓名,出生年份,(2009-出生年份)as年齡
(營(yíng)業(yè)員)這個(gè)廣義投影的第四個(gè)屬性被命名為年齡。對(duì)表3.1應(yīng)用上述運(yùn)算,得到的結(jié)果如表3.16所示。表3.16
工號(hào),姓名,出生年份,(2009-出生年份)as年齡
(營(yíng)業(yè)員)3.3.2聚集運(yùn)算在數(shù)據(jù)庫(kù)處理中,經(jīng)常需要計(jì)算總數(shù)、平均值、最大值等聚集操作,所以查詢系統(tǒng)提供了對(duì)數(shù)據(jù)的聚集運(yùn)算。
1.聚集函數(shù)(AggregateFunction)聚集函數(shù)通常對(duì)一個(gè)輸入集合進(jìn)行計(jì)算,然后將單一值作為結(jié)果返回。有時(shí),在計(jì)算聚集函數(shù)前,還必須去除重復(fù)值。去除重復(fù)值,仍然使用所需的聚集函數(shù)名,但用連字符將“Distinct”附加在函數(shù)名后。常用的聚集函數(shù)如表3.17所示。表3.17常用的聚集函數(shù)
2.聚集運(yùn)算(AggregateOperation)聚集運(yùn)算g的形式定義如下:其中E是任意關(guān)系代數(shù)表達(dá)式,G1,G2,…,Gn是用于聚集分組的一系列屬性;每個(gè)Fi是一個(gè)聚集函數(shù),每個(gè)Ai是一個(gè)屬性名。該運(yùn)算的含義是:表達(dá)式E中的元組被分成若干組,使得同一組中所有元組在G1,G2,…,Gn上的值相同,而不同組中元組在G1,G2,…,Gn上的值不同。例3.10參照表3.3“銷售”關(guān)系,按照“工號(hào)”對(duì)商品代碼元組分組,這樣每個(gè)分組將包含同一個(gè)營(yíng)業(yè)員賣出的不同商品代碼的商品。接著可以計(jì)算出每一個(gè)工號(hào)所對(duì)應(yīng)的銷售數(shù)量的平均值。該運(yùn)算可以表示為工號(hào)gavg(銷售數(shù)量)(銷售)聚集分組中間結(jié)果如表3.18所示。但這不是聚集計(jì)算的最終結(jié)果,最終結(jié)果需要去掉無(wú)用的列和重復(fù)的元組。該運(yùn)算的最終結(jié)果如表3.19所示。表3.18聚集分組中間結(jié)果表3.19聚集運(yùn)算結(jié)果3.3.3外連接連接又叫內(nèi)連接(InnerJoin),它可以保證兩個(gè)表中所有的行都滿足連接條件,這使它具有局限性。在一些應(yīng)用中,需要使用外連接(OuterJoin)。在外連接中,某些不滿足條件的列也會(huì)顯示出來(lái),也就是說(shuō),只限制一個(gè)表中的行,而不限制另外一個(gè)表中的行。這種連接形式在許多情況下是非常有用的。外連接運(yùn)算是連接運(yùn)算的擴(kuò)展,可以處理缺失的信息。使用外連接運(yùn)算可以避免信息丟失。外連接只能用于兩個(gè)表,它改變了兩張表的數(shù)據(jù)匹配方式。外連接特別描述了當(dāng)一張表中的值在另一張表中不出現(xiàn)時(shí)該如何處理的問(wèn)題。
1.外連接的分類外連接可以是左外連接(LeftJoin或LeftOuterJoin)、右外連接(RightJoin或RightOuterJoin)或全外連接(FullOuterJoin或FullJoin)。這3種形式的外連接都需要計(jì)算連接,然后在連接結(jié)果上附加額外的元組。
1)左外連接左外連接的結(jié)果集中包含LEFTOUTER子句中指定的左表的所有行,而不僅僅是連接屬性所匹配后得到的行。如果左表的某行在右表中沒(méi)有相應(yīng)的匹配行,則在左外連接的結(jié)果集中添加一個(gè)特殊元組,該元組左半部分由左表的未匹配的元組構(gòu)成,而其右半部分由對(duì)應(yīng)右表的一個(gè)空行構(gòu)成。
2)右外連接右外連接和左外連接相反,其結(jié)果將返回右表的所有行,如果右表的某行在左表中沒(méi)有匹配行,則將其與左表一個(gè)空行組合成一個(gè)結(jié)果元組。
3)全外連接全外連接返回左表和右表中的所有行。當(dāng)某行在另一個(gè)表中沒(méi)有匹配行時(shí),則將其與一個(gè)空行匹配構(gòu)成一個(gè)結(jié)果元組。
4)內(nèi)連接與外連接的區(qū)別內(nèi)連接消除了與另一個(gè)表中的任何行不匹配的行。注意:使用外連接必須小心,特別是全外連接。兩張沒(méi)有公共數(shù)據(jù)的規(guī)模比較大的表的連接結(jié)果十分巨大且沒(méi)有意義。
2.外連接實(shí)例
例3.11
查詢所有銷售人員的個(gè)人信息及其銷售信息。如果內(nèi)連接可以表示為:營(yíng)業(yè)員??銷售,這時(shí)查詢結(jié)果如表3.20所示。從表3.20可知,營(yíng)業(yè)員李冰、趙欣、趙潔和王小川已經(jīng)丟失,可見(jiàn)內(nèi)連接已經(jīng)不能滿足查詢需求??梢杂米笸膺B接實(shí)現(xiàn)這個(gè)查詢,查詢結(jié)果如表3.21所示。表3.20內(nèi)連接的查詢結(jié)果表3.21營(yíng)業(yè)員和銷售的左外連接的結(jié)果3.4數(shù)據(jù)庫(kù)的修改操作本節(jié)討論數(shù)據(jù)庫(kù)添加、刪除和修改等運(yùn)算操作。3.4.1數(shù)據(jù)刪除刪除操作形式定義如下:R?←?R?–?E,其中R是關(guān)系而E是關(guān)系代數(shù)查詢。下面列舉幾個(gè)關(guān)系代數(shù)中刪除請(qǐng)求的例子。
例3.12在“營(yíng)業(yè)員”關(guān)系中刪除李冰的所有記錄。營(yíng)業(yè)員?←?營(yíng)業(yè)員?-?σ姓名=“李冰”(營(yíng)業(yè)員)
例3.13刪除銷售價(jià)格在0~1000之間的所有商品。商品?←?商品?~?σ銷售價(jià)格>=0∧銷售價(jià)格<=1000(商品)
例3.14刪除營(yíng)業(yè)員張杰所銷售的所有商品。R?←σ姓名=“張杰”(營(yíng)業(yè)員?????銷售)S?←π商品代碼(R)商品?←?商品?-?σ銷售代碼∈S(商品)3.4.2數(shù)據(jù)插入向關(guān)系中插入數(shù)據(jù),可以插入一個(gè)元組,也可以插入一個(gè)查詢結(jié)果的集合。插入操作在關(guān)系代數(shù)中的形式定義如下:R←R∪E其中R是關(guān)系,E是關(guān)系代數(shù)表達(dá)式。如果E是只包含一個(gè)元組的常量,就表示向關(guān)系中插入單個(gè)元組。
例3.15向銷售關(guān)系中插入營(yíng)業(yè)員金文銷售了10臺(tái)T002的信息。該插入操作可以表示為V?←π工號(hào)(σ姓名=“金文”(營(yíng)業(yè)員))營(yíng)業(yè)員?←?營(yíng)業(yè)員∪{(V,T002,10)}
例3.16查詢所有已經(jīng)銷售的商品的基本信息、銷售數(shù)量以及相應(yīng)銷售人員的信息,并把查詢結(jié)果形成新的查詢關(guān)系。該查詢可以表示為R?←?(商品???銷售???營(yíng)業(yè)員)3.4.3數(shù)據(jù)更新在某些情況下,可以用廣義投影運(yùn)算來(lái)改變?cè)M中的某個(gè)值,其形式定義如下:
R?←其中,當(dāng)?shù)趇個(gè)屬性不被修改時(shí),F(xiàn)i是R的第i個(gè)屬性;當(dāng)?shù)趇個(gè)屬性將被修改時(shí),F(xiàn)i是一個(gè)只涉及常量和R的屬性表達(dá)式,該表達(dá)式給出了此屬性的新值。如果希望選出一些元組并只對(duì)這些元組進(jìn)行修改,可以用下述表達(dá)式:
R?←
(σP(R))∪(R?-σP(R))P代表用于選擇需要修改的元組的條件。
例3.17將所有商品價(jià)格增加10%,可以表示為商品?←π商品代碼,商品名稱,生產(chǎn)商,銷售價(jià)格*1.1(商品)
例3.18將銷售價(jià)格超過(guò)1500的價(jià)格增加5%,其余價(jià)格均增加10%。該操作可以表示為商品?←π商品代碼,商品名稱,生產(chǎn)商,銷售價(jià)格*1.05(σ銷售價(jià)格?>1500(商品))∪π商品代碼,商品名稱,生產(chǎn)商,銷售價(jià)格*1.1(σ銷售價(jià)格?<=1500(商品))3.5SQL
SQL是英文StructuredQueryLanguage的縮寫,譯為結(jié)構(gòu)化查詢語(yǔ)言,是一種介于關(guān)系代數(shù)與關(guān)系運(yùn)算之間的語(yǔ)言,目前已成為關(guān)系數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)語(yǔ)言。SQL語(yǔ)言之所以能夠?yàn)橛脩艉蜆I(yè)界所接受,成為國(guó)際標(biāo)準(zhǔn),是因?yàn)樗且粋€(gè)綜合、通用、功能極強(qiáng)同時(shí)又簡(jiǎn)潔易學(xué)的語(yǔ)言。SQL語(yǔ)言集數(shù)據(jù)查詢(DataQuery)、數(shù)據(jù)操縱(DataManipulation)、數(shù)據(jù)定義(DataDefinition)和數(shù)據(jù)控制(DataControl)功能于一體,充分體現(xiàn)了關(guān)系數(shù)據(jù)語(yǔ)言的特點(diǎn)和優(yōu)點(diǎn)。下面介紹SQL語(yǔ)言的主要特點(diǎn)。
1.一體化
SQL語(yǔ)言集數(shù)據(jù)定義語(yǔ)言DDL、數(shù)據(jù)操縱語(yǔ)言DML、數(shù)據(jù)控制語(yǔ)言DCL的功能于一體,所以其語(yǔ)言風(fēng)格統(tǒng)一,可以獨(dú)立完成數(shù)據(jù)庫(kù)生命周期中的全部活動(dòng),包括定義關(guān)系模式、錄入數(shù)據(jù)、建立數(shù)據(jù)庫(kù)、查詢、更新、維護(hù)、數(shù)據(jù)庫(kù)重構(gòu)、數(shù)據(jù)庫(kù)安全性控制等一系列操作要求,這就為數(shù)據(jù)庫(kù)應(yīng)用系統(tǒng)開(kāi)發(fā)者提供了友好的環(huán)境。例如用戶在數(shù)據(jù)庫(kù)投入運(yùn)行后,可根據(jù)需要隨時(shí)逐步修改模式,而不影響數(shù)據(jù)庫(kù)的運(yùn)行,因此使系統(tǒng)具有良好的可擴(kuò)充性。
2.高度非過(guò)程化非關(guān)系數(shù)據(jù)模型的數(shù)據(jù)操縱語(yǔ)言是面向過(guò)程的語(yǔ)言,用其完成某項(xiàng)請(qǐng)求,必須指定存取路徑。而用SQL語(yǔ)言進(jìn)行數(shù)據(jù)操作,用戶只需提出“做什么”,而不必指明“怎么做”,因此用戶無(wú)需了解存取路徑,存取路徑的選擇以及SQL語(yǔ)句的操作過(guò)程由系統(tǒng)自動(dòng)完成。這不但大大減輕了用戶負(fù)擔(dān),而且有利于提高數(shù)據(jù)獨(dú)立性。
3.簡(jiǎn)潔
SQL語(yǔ)言功能極強(qiáng),設(shè)計(jì)巧妙,語(yǔ)言十分簡(jiǎn)潔,完成數(shù)據(jù)定義、數(shù)據(jù)操縱、數(shù)據(jù)控制的核心功能只用了9個(gè)動(dòng)詞:CREATE、DROP、SELECT、INSERT、UPDATE、DELETE、GRANT、REVOKE;而且SQL語(yǔ)言語(yǔ)法簡(jiǎn)單,接近英語(yǔ)口語(yǔ),因此容易學(xué)習(xí)、容易使用。
4.能以多種方式使用
SQL語(yǔ)言既是自含式語(yǔ)言,又是嵌入式語(yǔ)言。作為自含式語(yǔ)言,它能夠獨(dú)立地用于聯(lián)機(jī)交互的使用方式,用戶可以在終終端鍵盤上直接鍵入SQL命令對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作。作為嵌入式語(yǔ)言,SQL語(yǔ)句能夠嵌入到高級(jí)語(yǔ)言(例如C、C++、JAVA)程序中,供程序員設(shè)計(jì)程序時(shí)使用。在兩種不同的使用方式下,SQL語(yǔ)言的語(yǔ)法結(jié)構(gòu)基本上是一致的。這種以統(tǒng)一的語(yǔ)法結(jié)構(gòu)提供兩種不同的使用方式的做法,為用戶提供了極大的靈活性與方便性。
5.面向集合的操作方式
SQL語(yǔ)言采用集合操作方式,不僅查找結(jié)果可以是元組的集合,而且一次插入、刪除、更新操作的對(duì)象也是元組的集合。3.5.1SQL基本結(jié)構(gòu)
SQL的功能分成4部分:數(shù)據(jù)定義、數(shù)據(jù)查詢、數(shù)據(jù)操縱、數(shù)據(jù)控制。SQL語(yǔ)言的動(dòng)詞如表3.22所示。本節(jié)將使用連鎖超市數(shù)據(jù)庫(kù)中的3個(gè)關(guān)系來(lái)學(xué)習(xí)SQL的用法。表3.23~3.25分別代表營(yíng)業(yè)員、銷售和商品3個(gè)關(guān)系。為了描述SQL需要,這里定義的3個(gè)關(guān)系與表3.1、表3.4、表3.5所示的有所不同。表3.22SQL語(yǔ)言的主要?jiǎng)釉~表3.23“營(yíng)業(yè)員”表
表3.24“銷售”表表3.25“商品”表
1.?dāng)?shù)據(jù)庫(kù)的創(chuàng)建和刪除
(1)創(chuàng)建數(shù)據(jù)庫(kù)的語(yǔ)法格式如下:CREATEDATABASE<數(shù)據(jù)庫(kù)名>;其中,CREATEDATABASE是關(guān)鍵字,本書后面的關(guān)鍵字均用大寫字母書寫。SQL以“;”作為語(yǔ)句分割符,表示一個(gè)SQL語(yǔ)句結(jié)束。例3.19
建立“超市”數(shù)據(jù)庫(kù)。代碼如下:CREATEDATABASE超市;
(2)刪除數(shù)據(jù)庫(kù)的語(yǔ)法格式如下:DROPDATABASE<數(shù)據(jù)庫(kù)名><CASCADE|RESTRICT>其中,若使用CASCADE(級(jí)聯(lián)),則在刪除數(shù)據(jù)庫(kù)的同時(shí)把該數(shù)據(jù)庫(kù)中所有的數(shù)據(jù)庫(kù)對(duì)象全部刪除;若使用RESTRICT(限制),則該數(shù)據(jù)庫(kù)中如果定義了下屬的數(shù)據(jù)庫(kù)對(duì)象(如表、視圖等),會(huì)拒絕該刪除語(yǔ)句的執(zhí)行。只有當(dāng)該數(shù)據(jù)庫(kù)中沒(méi)有任何下屬的對(duì)象時(shí)才能執(zhí)行刪除操作。
例3.20刪除“超市”數(shù)據(jù)庫(kù),同時(shí)刪除該數(shù)據(jù)庫(kù)中所定義的表。該操作的代碼如下:DROPDATABASE超市CASCADE;
2.基本表的定義在SQL中關(guān)系稱為“表”、元組稱為“行”、屬性稱為“列”。有時(shí)“表”也稱為基本表。
1)創(chuàng)建基本表創(chuàng)建表的語(yǔ)法格式如下:
CREATETABLE<表名>
(<列名><數(shù)據(jù)類型>[<列級(jí)完整性約束條件>]
[,<列名><數(shù)據(jù)類型>[<列級(jí)完整性約束條件>]]…
[,<表級(jí)完整性約束條件>]);其中,如果完整性約束條件涉及到該表的多個(gè)屬性列,則必須定義在表級(jí)上,否則既可以定義在列級(jí)上也可以定義在表級(jí)上。
例3.21在“超市”數(shù)據(jù)庫(kù)中創(chuàng)建“營(yíng)業(yè)員”、“商品”和“銷售”3個(gè)表。該創(chuàng)建操作的代碼如下:
CREATETABLE營(yíng)業(yè)員
(工號(hào)CHAR(6)PRIMARYKEY,姓名CHAR(6),工作年月CHAR(8),出生年月CHAR(8),聯(lián)系電話CHAR(8));
CREATETABLE商品
(商品代碼CHAR(6)PRIMARYKEY,商品名稱CHAR(20),生產(chǎn)商CHAR(20),銷售價(jià)格FLOAT(2),生產(chǎn)日期DATETIME);
CREATETABLE銷售
(工號(hào)CHAR(6),商品代碼CHAR(6),銷售日期DATETIME,銷售數(shù)量INT,
PRIMARYKEY(工號(hào),商品代碼),
FOREIGNKEY(工號(hào))REFERENCES營(yíng)業(yè)員(工號(hào)),
FOREIGNKEY(商品代碼)REFERENCES商品(商品代碼));其中,基本表的每個(gè)列是一個(gè)原子的數(shù)據(jù)變量,具有一定的數(shù)據(jù)類型和約束條件描述。在創(chuàng)建營(yíng)業(yè)員表的SQL語(yǔ)句中,“工號(hào)CHAR(6)PRIMARYKEY”表示“工號(hào)”列是一個(gè)長(zhǎng)度為6個(gè)字符的字符串;PRIMARYKEY是一個(gè)約束條件,表示該列是“營(yíng)業(yè)員”表的主碼。在創(chuàng)建銷售表的SQL語(yǔ)句中,“FOREIGNKEY(工號(hào))REFERENCES營(yíng)業(yè)員(工號(hào))”定義了表級(jí)的約束條件,表示“工號(hào)”列是該表的外碼,對(duì)應(yīng)于“營(yíng)業(yè)員”表的工號(hào)列。
SQL中域的概念用數(shù)據(jù)類型來(lái)實(shí)現(xiàn),定義表的屬性時(shí),需要指明其數(shù)據(jù)類型及長(zhǎng)度。表3.26列出了SQL的主要數(shù)據(jù)類型。表3.26SQL主要數(shù)據(jù)類型表
2)修改基本表結(jié)構(gòu)修改基本表的語(yǔ)法格式如下:
ALTERTABLE<表名>
[ADD<新列名><數(shù)據(jù)類型>[完整性約束]]
[DROP<完整性約束名>]
[ALTERCOLUMN<列名><數(shù)據(jù)類型>];其中,<表名>是要修改的基本表,ADD子句用來(lái)向基本表增加一個(gè)新列或新的完整性約束條件,DROP子句用于刪除指定的完整性約束條件,ALTERCOLUMN子句用于修改原有列的定義,包括修改列名和數(shù)據(jù)類型。
例3.22向“營(yíng)業(yè)員”表增加“家庭地址”列。
ALTERTABLE營(yíng)業(yè)員ADD家庭地址CHAR(10);例3.23
將“營(yíng)業(yè)員”表的聯(lián)系電話列的數(shù)據(jù)類型改為整型。
ALTERTABLE營(yíng)業(yè)員ALTER聯(lián)系電話INT;例3.24
向“商品”表增加“商品名稱必須取唯一值”的約束條件。
ALTERTABLE商品ADDUNIQUE(商品名稱);
3)刪除基本表刪除基本表的語(yǔ)法格式如下:
DROPTABLE<表名><CASCADE|RESTRICT>其中,若使用CASCADE(級(jí)聯(lián)),則在刪除表的同時(shí)把相關(guān)的依賴對(duì)象全部刪除;若使用RESTRICT(限制),則如果該表被其他表的約束所引用,或者該表上建立了視圖、觸發(fā)器、存儲(chǔ)過(guò)程等,會(huì)拒絕該刪除語(yǔ)句的執(zhí)行;缺省時(shí)是RESTRICT。
例3.25刪除營(yíng)業(yè)員基本情況表。
DROPTABLE營(yíng)業(yè)員CASCADE;
3.索引的建立與刪除建立索引是加快查詢速度的有效手段。用戶可以根據(jù)需要,在基本表上建立一個(gè)或多個(gè)索引。建立合理的索引,可以加速數(shù)據(jù)的檢索過(guò)程。
SQLServer采用B-?樹(shù)結(jié)構(gòu)的索引,根據(jù)索引的順序與數(shù)據(jù)表的物理順序是否相同可以分為:聚集索引(ClusteredIndex)和非聚集索引(NonclusteredIndex)。
(1)聚集索引重新組織表中的數(shù)據(jù)以按指定的一個(gè)或多個(gè)列的值排序。聚集索引的葉節(jié)點(diǎn)包含實(shí)際的數(shù)據(jù),因此用它查找數(shù)據(jù)很快,但每個(gè)表只能建立一個(gè)聚集索引。建立聚集索引后,更新該列上的數(shù)據(jù)時(shí),往往會(huì)導(dǎo)致表中記錄的物理順序的變更,代價(jià)較大,所以對(duì)于經(jīng)常更新的列不宜建立聚集索引。
(2)非聚集索引不重新組織表中的數(shù)據(jù),它的葉節(jié)點(diǎn)存儲(chǔ)了組成非聚集索引的列值和行的定位指針。一個(gè)表可以建立249個(gè)非聚集索引。
1)聚集索引的使用在聚集索引下,數(shù)據(jù)在物理上按順序排在數(shù)據(jù)頁(yè)上,重復(fù)值也排在一起,因而在那些包含范圍檢查(BETWEEN、<、<=、>、>=)或使用GROUPBY、ORDERBY的查詢時(shí),一旦找到具有范圍中第一個(gè)鍵值的行,具有后續(xù)索引值的行一定連在一起,不必進(jìn)一步搜索,避免了大范圍掃描,可以大大提高查詢速度。
2)非聚集索引的使用由于非聚集索引的葉節(jié)點(diǎn)不包含實(shí)際的數(shù)據(jù),因此它檢索效率較低,但是一個(gè)表只可以建立一個(gè)聚集索引,當(dāng)用戶需要建立多個(gè)索引時(shí)就需要使用非聚集索引了。在建立非聚集索引時(shí),要權(quán)衡索引加快查詢速度與降低修改速度之間的利弊。總之,在良好的數(shù)據(jù)庫(kù)設(shè)計(jì)基礎(chǔ)上,有效地使用索引是數(shù)據(jù)庫(kù)應(yīng)用系統(tǒng)取得高性能的基礎(chǔ)。然而,任何事物都具有兩面性,索引也不例外。索引的建立需要占用額外的存儲(chǔ)空間,并且在增、刪、改的操作中也會(huì)增加一定的工作量,在適當(dāng)?shù)牡胤皆黾舆m當(dāng)?shù)乃饕?,從不合理的地方刪除次要的索引,將有助于優(yōu)化那些性能較差的數(shù)據(jù)庫(kù)應(yīng)用系統(tǒng)。
3)建立索引建立索引語(yǔ)法格式如下:
CREATE[UNIQUE][CLUSTER]INDEX<索引名>
ON<表名>(<列名>[<次序>][,<列名>[<次序>]]…);其中,<表名>是要建立索引的基本表的名字。索引可以建立在該表的一列或多個(gè)列上,各列間用逗號(hào)分隔。每個(gè)<列名>后面還可以用<次序>指定索引值的排列次序,可以選ASC(升序)或DESC(降序),缺省值為ASC。UNIQUE表明此索引的每一個(gè)索引值只能對(duì)應(yīng)唯一的數(shù)據(jù)記錄。CLUSTERED表示要建立的索引是聚集索引。例3.26在營(yíng)業(yè)員表的姓名列上建立一個(gè)聚集索引。
CREATECLUSTEREDINDEX營(yíng)業(yè)員-姓名ON營(yíng)業(yè)員(姓名);
例3.27營(yíng)業(yè)員表按工號(hào)升序建立唯一索引。
CREATEINDEX營(yíng)業(yè)員-工號(hào)ON營(yíng)業(yè)員(工號(hào));
例3.28商品表按商品代碼升序建立唯一索引。
CREATEINDEX商品-商品代碼ON商品(商品代碼);
例3.29銷售表按工號(hào)升序和商品代碼降序建立唯一索引。
CREATEINDEX工號(hào)-商品代碼ON銷售(工號(hào)ASC,商品代碼DESC);
4)刪除索引刪除索引語(yǔ)法格式如下:
DROPINDEX<索引名>;刪除索引時(shí),系統(tǒng)會(huì)從數(shù)據(jù)字典中刪去有關(guān)該索引的描述。
例3.30刪除例3.28所建立的“營(yíng)業(yè)員-工號(hào)”索引。
DROPINDEX營(yíng)業(yè)員-工號(hào);
4.?dāng)?shù)據(jù)的查詢查詢語(yǔ)句的語(yǔ)法格式如下:
SELECT[ALL|DISTINCT]<目標(biāo)列表達(dá)式>[,<目標(biāo)列表達(dá)式>]…
FROM<表名或視圖名>[,<表名或視圖名>]…
[WHERE<條件表達(dá)式>]
[GROUPBY<分組依據(jù)列>]
[HAVING<條件表達(dá)式>]
[ORDERBY<排序依據(jù)列>[ASC|DESC]];其中,根據(jù)WHERE子句的條件表達(dá)式,從FROM子句制定的基本表或視圖中找出滿足條件的元組,再按照SELECT子句中的目標(biāo)列表達(dá)式,選出元組中的屬性值形成結(jié)果表。如果有GROUPBY子句,則將結(jié)果按分組的列值進(jìn)行分組,該屬性列值相等的元組為一個(gè)組,通常在每組中會(huì)應(yīng)用聚集函數(shù)。如果GROUPBY子句中包含HAVING短語(yǔ),則只有滿足制定條件的組才給予輸出。如果有ORDERBY子句,則將結(jié)果表按照排序依據(jù)列的值進(jìn)行升序或降序排列。
SELECT語(yǔ)句可以進(jìn)行單表查詢、復(fù)雜的連接查詢、嵌套查詢。單表查詢僅僅涉及一個(gè)表。下面以連鎖超市數(shù)據(jù)庫(kù)中的3張表為例學(xué)習(xí)單表查詢。
1)簡(jiǎn)單查詢?cè)跀?shù)據(jù)庫(kù)中,一般情況下,每個(gè)表都包含若干個(gè)列信息。用戶在查詢表中的記錄時(shí),大多數(shù)情況下只是關(guān)心表的一列或者幾列的信息。這時(shí),只需要使用SELECT語(yǔ)句的常規(guī)使用方式即可。語(yǔ)法格式如下:
SELECT列名1[,列名2,…列名n]
FROM表名;其中,SELECT關(guān)鍵詞指明要查詢的表的列名,F(xiàn)ROM關(guān)鍵詞指明要查詢的列所在的表名。
例3.31[查詢單列數(shù)據(jù)]查詢?nèi)w營(yíng)業(yè)員的姓名。本例代碼如下:
SELECT姓名
FROM營(yíng)業(yè)員;運(yùn)行該代碼,得到的查詢結(jié)果如圖3.3所示。在SQL語(yǔ)言中,SQL關(guān)鍵詞對(duì)大小寫不敏感,所以對(duì)SELECT關(guān)鍵詞來(lái)說(shuō),SELECT、select或者Select都是一樣的。在SQLSERVER中,其字段名稱對(duì)大小寫也不敏感。圖3.3查詢姓名列的數(shù)據(jù)例3.32[查詢多列數(shù)據(jù)]查詢?nèi)w營(yíng)業(yè)員的工號(hào)、姓名及其工作年月。本例代碼如下:
SELECT工號(hào),姓名,工作年月
FROM營(yíng)業(yè)員運(yùn)行該代碼,得到的查詢結(jié)果如圖3.4所示。多列查詢需要在SELECT關(guān)鍵詞后指定要查詢的列,但是各列之間必須用逗號(hào)分開(kāi)。圖3.4查詢多列數(shù)據(jù)的結(jié)果例3.33[去除查詢結(jié)果的重復(fù)信息—DISTINCT]查詢銷售表中所有銷售員的工號(hào),即查詢工號(hào)列的數(shù)據(jù),且去除重復(fù)的記錄。前面介紹的最基本的查詢方式會(huì)返回從表格中搜索到的所有行的數(shù)據(jù),而不管這些數(shù)據(jù)是否重復(fù),這常常不是用戶希望看到的。使用DISTINCT關(guān)鍵字就能夠從返回的結(jié)果數(shù)據(jù)集合中刪除重復(fù)的行,使返回的結(jié)果更簡(jiǎn)潔。在SELECT子句中,通過(guò)指明DISTINCT關(guān)鍵字去除列中的重復(fù)信息。語(yǔ)法如下:
SELECTDISTINCT列名FROM表名;其中,DISTINCT關(guān)鍵字去除的是SELECT子句查詢的列的重復(fù)信息。如果SELECT子句查詢的列為多列,那么只有這些列的信息同時(shí)重復(fù)的記錄才被去除。本例代碼如下:
SELECTDISTINCT工號(hào)
FROM銷售;運(yùn)行該代碼,得到的查詢結(jié)果如圖3.5所示。以上結(jié)果集中的重復(fù)記錄被刪除了,同時(shí)對(duì)結(jié)果集中的數(shù)據(jù)按照升序進(jìn)行了排序。實(shí)際上,DBMS的操作過(guò)程是先對(duì)查詢結(jié)果排序,而后查找并去除結(jié)果集中重復(fù)的值。使用DISTINCT是要付出代價(jià)的。因?yàn)橐サ糁貜?fù)值,必須對(duì)結(jié)果集中的記錄進(jìn)行排序,使得相同的記錄聚集在一起,只有按這種方法對(duì)記錄進(jìn)行分組,才能去掉重復(fù)值,而這一工作甚至比查詢本身還費(fèi)時(shí)間。在使用DISTINCT關(guān)鍵字后,如果表中有多個(gè)為NULL的數(shù)據(jù),服務(wù)器會(huì)把這些數(shù)據(jù)視為相等。圖3.5去除重復(fù)信息的工號(hào)列的數(shù)據(jù)例3.34[用“*”查詢所有列]?查詢?nèi)w營(yíng)業(yè)員的所有列信息。除了能夠進(jìn)行單列查詢和多列查詢以外,使用SELECT語(yǔ)句還可以查詢表中的所有列,這是通過(guò)星號(hào)(?*?)通配符實(shí)現(xiàn)的。語(yǔ)法如下:
SELECT*FROM表名;使用“*”通配符,查詢結(jié)果將顯示表中所有列的元素,因此無(wú)需指明各列的列名,這在用戶不清楚表中各列的列名時(shí)非常有用。服務(wù)器會(huì)按用戶創(chuàng)建表時(shí)所聲明的列的順序來(lái)顯示所有的列。本例代碼如下:
SELECT*
FROM營(yíng)業(yè)員;運(yùn)行該代碼,得到的查詢結(jié)果如圖3.6所示。圖3.6營(yíng)業(yè)員表中所有列的記錄
注意:使用“?*?”通配符時(shí)要慎重,在不需要查詢所有列時(shí),盡量采用前面介紹的單列查詢或多列查詢,以免占用過(guò)多的資源。
2)帶有搜索條件的查詢一個(gè)數(shù)據(jù)表中存放著大量相關(guān)的記錄數(shù)據(jù)。實(shí)際使用時(shí),往往只需要其中滿足要求的部分記錄,這時(shí)就需要用到WHERE條件子句。WHERE子句允許指定查詢條件,使得SELECT語(yǔ)句的結(jié)果表中只包含那些滿足查詢條件的記錄。語(yǔ)法格式如下:
SELECT列名1[,列名2,…列名n]FROM表名WHERE條件;其中,WHERE子句必須緊跟在FROM子句后面。SQLSERVER對(duì)WHERE子句中的查詢條件的數(shù)目沒(méi)有限制。WHERE子句中的條件表達(dá)式包括算術(shù)表達(dá)式和邏輯表達(dá)式兩種,表達(dá)式中通常包含一些操作符。表3.27給出了WHERE子句中允許使用的操作符?!癖容^操作符的用法在對(duì)字符串類型的字段使用比較操作符時(shí),是根據(jù)字符的排列順序進(jìn)行比較的。字符串的排序是根據(jù)其首字母的順序進(jìn)行的,如果首字符相同,則比較下一個(gè)字符,依此類推。對(duì)于漢字的排序,是根據(jù)其漢語(yǔ)拼音的第一個(gè)字母的順序進(jìn)行的,如果第一個(gè)字母相同,則比較第二個(gè)字母,依此類推,且漢字的順序要高于字母的順序。表3.27操作符列表例3.35
查詢“銷售”表中“商品代碼”為T002的記錄。本例代碼如下:
SELECT*
FROM銷售
WHERE商品代碼='T002';運(yùn)行該代碼,得到的查詢結(jié)果如圖3.7所示。圖3.7銷售表中“商品代碼”為T002的記錄例3.36
查詢“營(yíng)業(yè)員”表中“出生年月”大于1972年的營(yíng)業(yè)員的姓名和出生年月。本例代碼如下:
SELECT姓名,出生年月
FROM營(yíng)業(yè)員
WHEREleft(出生年月,4)>'1972';運(yùn)行該代碼,得到的查詢結(jié)果如圖3.8所示。圖3.8出生年月大于1972年的記錄例3.37
在“營(yíng)業(yè)員”表中查年齡不大于38歲的營(yíng)業(yè)員的姓名、工號(hào)、出生年月。本例代碼如下:
SELECT姓名,工號(hào),出生年月
FROM營(yíng)業(yè)員
WHERE2009-LEFT(出生年月,4)!?>?38;運(yùn)行該代碼,得到的查詢結(jié)果如圖3.9所示?!袷褂没镜倪壿嫳磉_(dá)式——NOT、AND、OR在WHERE子句中,可以使用多個(gè)搜索條件選擇記錄(行),即通過(guò)邏輯運(yùn)算符(NOT、AND或OR)將多個(gè)單獨(dú)的搜索條件結(jié)合在一個(gè)WHERE子句中,形成一個(gè)復(fù)合的搜索條件。當(dāng)對(duì)復(fù)合搜索條件求值時(shí),DBMS對(duì)每個(gè)單獨(dú)的搜索條件求值,然后執(zhí)行布爾運(yùn)算來(lái)決定整個(gè)WHERE子句的值是TRUE還是FALSE。只有那些滿足整個(gè)WHERE子句的值是TRUE的記錄才出現(xiàn)在結(jié)果表中。圖3.9年齡不大于38歲的記錄例3.38[使用AND運(yùn)算符進(jìn)行條件查詢]?在銷售表中,查詢“銷售數(shù)量”小于20的“商品代碼”為T002的記錄。
AND運(yùn)算符表示邏輯“與”的關(guān)系。當(dāng)使用AND運(yùn)算符組合兩個(gè)邏輯表達(dá)式時(shí),只有當(dāng)兩個(gè)表達(dá)式均為TRUE時(shí)才返回TRUE。本例代碼如下:
SELECT*
FROM銷售
WHERE銷售數(shù)量<15and商品代碼?=?'T002';運(yùn)行該代碼,得到的查詢結(jié)果如圖3.10所示。注意:當(dāng)語(yǔ)句中使用多個(gè)邏輯運(yùn)算符時(shí),將首先計(jì)算AND運(yùn)算符,使用括號(hào)也可以改變求值順序。
圖3.10“銷售數(shù)量”小于20的“商品代碼”為T002的記錄例3.39[使用OR運(yùn)算符進(jìn)行條件查詢]?在銷售表中,查詢銷售數(shù)量小于15或商品代碼為T003的記錄。
OR運(yùn)算符實(shí)現(xiàn)邏輯“或”的運(yùn)算關(guān)系。當(dāng)使用OR運(yùn)算符組合兩個(gè)邏輯表達(dá)式時(shí),只要其中一個(gè)表達(dá)式的條件為TRUE,結(jié)果便返回TRUE。
本例代碼如下:
SELECT*
FROM銷售
WHERE銷售數(shù)量?<?15or商品代碼?=?'T003';運(yùn)行該代碼,得到的查詢結(jié)果如圖3.11所示。注意:OR運(yùn)算符的優(yōu)先級(jí)低于AND運(yùn)算符,即在AND運(yùn)算符之后才對(duì)OR運(yùn)算符求值。不過(guò),使用括號(hào)可以更改求值的順序。圖3.11銷售數(shù)量小于15或商品代碼為T003的記錄例3.40[使用NOT運(yùn)算符進(jìn)行條件查詢]?在商品表中,查詢非T001的記錄。
NOT運(yùn)算符實(shí)現(xiàn)邏輯“非”的運(yùn)算關(guān)系,用于對(duì)搜索條件的邏輯值求反。代碼如下:
SELECT*
FROM商品
WHERENOT商品代碼?=?'T001';運(yùn)行該代碼,得到的查詢結(jié)果如圖3.12所示。NOT運(yùn)算符對(duì)緊跟其后的條件取反,在本例中,“NOT商品代碼?=?'T001'?”語(yǔ)句實(shí)際上就等價(jià)于“商品代碼!=?'T001'”或者“商品代碼?<>?'T001'”語(yǔ)句。注意:NOTNULL的結(jié)果仍為NULL。圖3.12不包含商品代碼為T001的記錄例3.41[基本邏輯運(yùn)算符的組合使用]?在銷售表中,查詢所有T003和T002商品并且銷售數(shù)量不高于15的銷售記錄。在WHERE子句中,各種邏輯運(yùn)算符可以組合使用,即AND、OR、NOT運(yùn)算符可以同時(shí)使用。與使用算術(shù)運(yùn)算符進(jìn)行運(yùn)算一樣,使用邏輯運(yùn)算符也存在運(yùn)算優(yōu)先級(jí)的問(wèn)題。在這3種邏輯運(yùn)算符中,NOT運(yùn)算符的優(yōu)先級(jí)最高,而后是AND,最后是OR。本例代碼如下:
SELECT*
FROM銷售
WHERE商品代碼?=?'T003'OR商品代碼?=?'T002'ANDNOT銷售數(shù)量>15;運(yùn)行該代碼,得到的查詢結(jié)果如圖3.13所示。圖3.13沒(méi)有得到預(yù)期的查詢結(jié)果圖3.13所示的查詢結(jié)果,顯然并沒(méi)有得到預(yù)期的效果。根據(jù)邏輯運(yùn)算符的優(yōu)先級(jí)順序,WHERE子句中代碼的執(zhí)行過(guò)程如下:首先DBMS執(zhí)行NOT運(yùn)算,即結(jié)果集中的記錄需要滿足銷售數(shù)量不大于15;而后DBMS執(zhí)行AND運(yùn)算,即結(jié)果集中的記錄需要滿足T002商品且銷售數(shù)量不大于15;最后DBMS執(zhí)行OR運(yùn)算,即結(jié)果集中的記錄需要滿足T003商品或者滿足T002商品且銷售數(shù)量不大于15。以上查詢結(jié)果出現(xiàn)了本應(yīng)不出現(xiàn)的“T003商品的銷售數(shù)量為18”的記錄,如果要得到正確的結(jié)果,就要使用括號(hào)改變運(yùn)算的順序。代碼如下:
SELECT*
FROM銷售
WHERE(商品代碼?=?'T003'OR商品代碼?=?'T002')ANDNOT銷售數(shù)量>15;運(yùn)行該代碼,即得到了正確的查詢結(jié)果,如圖3.14所示。注意:當(dāng)OR運(yùn)算符和AND運(yùn)算符同時(shí)運(yùn)用時(shí),可以不考慮其默認(rèn)的優(yōu)先級(jí)順序,而是采用括號(hào)()來(lái)實(shí)現(xiàn)需要的執(zhí)行順序,這樣可以增強(qiáng)程序的可讀性。圖3.14得到預(yù)期的查詢結(jié)果●使用限定數(shù)據(jù)范圍——BETWEEN進(jìn)行查詢?cè)赪HERE子句中,使用BETWEEN關(guān)鍵字可以更方便地限制查詢數(shù)據(jù)的范圍。使用NOTBETWEEN關(guān)鍵字查詢也可以限定數(shù)據(jù)范圍之外的記錄。語(yǔ)法格式可表示如下:表達(dá)式[NOT]BETWEEN表達(dá)式1AND表達(dá)式2;比如,選擇范圍在10~100之間的數(shù),采用BETWEEN運(yùn)算符可以表示為
BETWEEN10AND100例3.42
查詢?cè)?970和1971年出生的營(yíng)業(yè)員的姓名,出生年月和聯(lián)系電話。本例代碼如下:
SELECT姓名,出生年月,聯(lián)系電話
FROM營(yíng)業(yè)員
WHEREleft(出生年月,4)BETWEEN1970AND1971;運(yùn)行該代碼,即得到了正確的查詢結(jié)果,如圖3.15所示。使用BETWEEN限制查詢數(shù)據(jù)范圍時(shí)同時(shí)也包括了邊界值,而使用NOTBETWEEN進(jìn)行查詢時(shí)沒(méi)有包括邊界值。也就是說(shuō),BETWEEN表達(dá)式可以用含有“>=”和“<=”的邏輯表達(dá)式來(lái)代替;NOTBETWEEN表達(dá)式可以用含有“>”和“<”的邏輯表達(dá)式來(lái)代替。圖3.15在1970和1971年出生的營(yíng)業(yè)員的記錄●使用限制檢索數(shù)據(jù)的范圍——IN進(jìn)行查詢
IN與BETWEEN關(guān)鍵字一樣,可以方便地限制檢索數(shù)據(jù)的范圍,靈活使用IN關(guān)鍵字,可以用簡(jiǎn)潔的語(yǔ)句實(shí)現(xiàn)結(jié)構(gòu)復(fù)雜的查詢。語(yǔ)法格式可表示如下:表達(dá)式[NOT]IN(表達(dá)式1,表達(dá)式2[,…表達(dá)式n])其中,所有的條件在IN運(yùn)算符后面羅列,并以括號(hào)()括起來(lái),條件中間用逗號(hào)分開(kāi)。當(dāng)要判斷的表達(dá)式處于括號(hào)中列出的一系列值之中時(shí),IN運(yùn)算符求值為TRUE。例3.43
在銷售表中,查詢工號(hào)為001、003和004的銷售員的銷售記錄。本例代碼如下:
SELECT*FROM銷售WHERE工號(hào)IN('001','003','004');運(yùn)行該代碼,得到的查詢結(jié)果如圖3.16所示。在多數(shù)情況下,OR運(yùn)算符與IN運(yùn)算符可以實(shí)現(xiàn)相同的功能。但使用IN運(yùn)算符更為簡(jiǎn)潔,特別是當(dāng)選擇的條件很多時(shí),只需在括號(hào)內(nèi)用逗號(hào)間隔各條件即可,其運(yùn)行效率也比OR運(yùn)算符要高。IN運(yùn)算符后面所有的條件也可以是另一條SELECT語(yǔ)句,即子查詢。這在后面的章節(jié)中會(huì)有詳細(xì)介紹。圖3.16工號(hào)為001、003和004的銷售員的銷售記錄●使用模糊查詢——LIKE進(jìn)行查詢實(shí)際上,當(dāng)查詢條件不很精確時(shí),需要根據(jù)一些并不確切的線索來(lái)搜索信息。采用LIKE子句可以進(jìn)行這類模糊搜索。語(yǔ)法格式可表示如下:表達(dá)式[NOT]LIKE條件
LIKE子句在大多數(shù)情況下會(huì)與通配符配合使用。SQLSERVER提供了4種通配符來(lái)實(shí)現(xiàn)復(fù)雜的模糊查詢條件,如表3.28所示。注意:通配符只有在LIKE子句中才有意義,否則通配符會(huì)被當(dāng)作普通字符處理。表3.28通配符列表例3.44[使用“%”通配符進(jìn)行任意字符串匹配的模糊查詢]?在商品表中,查詢商品名稱中含有“彩電”字符串的所有商品記錄?!?”通配符表示任意字符的匹配,且不計(jì)字符的多少。例如,“電器%”表示匹配以字符串“電器”開(kāi)頭的任意字符串;“%電器”表示匹配以字符串“電器”結(jié)尾的任意字符串;“%電器%”表示匹配含有字符串“電器”的任意字符串。本例代碼如下:
SELECT*FROM商品WHERE商品名稱LIKE'%彩電%';運(yùn)行該代碼,得到的查詢結(jié)果如圖3.17所示。商品名稱中所有含有“彩電”字符串的記錄均出現(xiàn)在結(jié)果表中,而不論其在商品名稱中的位置。圖3.17商品名稱中含有“彩電”字符串的商品記錄例3.45[使用“%”通配符指定開(kāi)頭或結(jié)尾字符匹配的模糊查詢]在營(yíng)業(yè)員表中,查詢所有姓張的營(yíng)業(yè)員的姓名、工號(hào)。本例代碼如下:
SELECT姓名,工號(hào)
FROM營(yíng)業(yè)員
WHERE姓名LIKE'張%';運(yùn)行該代碼,得到的查詢結(jié)果如圖3.18所示。圖3.18所有姓張的營(yíng)業(yè)員的記錄例3.46
[使用“%”通配符實(shí)現(xiàn)排除查詢]?在營(yíng)業(yè)員表中,查詢所有不姓張的營(yíng)業(yè)員的記錄,即姓名中不能以“張”字符開(kāi)頭。本例代碼如下:
SELECT*
FROM營(yíng)業(yè)員
WHERE姓名NOTLIKE'張%';運(yùn)行該代碼,得到的查詢結(jié)果如圖3.19所示。圖3.19不姓張的營(yíng)業(yè)員的記錄例3.47
[使用“_”通配符實(shí)現(xiàn)模糊查詢]在營(yíng)業(yè)員表中,查詢姓“張”且全名為兩個(gè)漢字的營(yíng)業(yè)員的記錄。與“%”通配符不同,“_”通配符只能匹配任何單個(gè)字符。例如,“張
”表示將查找以“張”開(kāi)頭的所有兩個(gè)漢字的字符串(“張杰”、“張雅”等)。若要表示兩個(gè)字符的匹配,需要使用兩個(gè)“_”通配符,即寫成“__”。本例代碼如下:
SELECT*
FROM營(yíng)業(yè)員
WHERE姓名LIKE'張_';運(yùn)行該代碼,得到的查詢結(jié)果如圖3.20所示。圖3.20姓“張”且全名為兩個(gè)漢字的營(yíng)業(yè)員的記錄例3.48
[同時(shí)使用“_”和“%”通配符實(shí)現(xiàn)模糊查詢]在營(yíng)業(yè)員表中,查詢姓名中第2個(gè)字為“文”的營(yíng)業(yè)員的記錄。本例代碼如下:
SELECT*
FROM營(yíng)業(yè)員
WHERE姓名LIKE'_文%';運(yùn)行該代碼,得到的查詢結(jié)果如圖3.21所示。圖3.21姓名中第2個(gè)字為“文”的營(yíng)業(yè)員的記錄●使用ESCAPE關(guān)鍵字定義轉(zhuǎn)義字符使用LIKE進(jìn)行模糊查詢時(shí),當(dāng)“%”、“_”符號(hào)單獨(dú)出現(xiàn)時(shí),就會(huì)被認(rèn)為是通配符。但有時(shí)可能需要搜索包含一個(gè)或多個(gè)特殊通配符的字符串。例如,數(shù)據(jù)庫(kù)表中可能存儲(chǔ)含百分號(hào)“%”的折扣值。若要搜索作為字符而不是通配符的百分號(hào),必須使用ESCAPE關(guān)鍵字和轉(zhuǎn)義符。如下面的語(yǔ)句:
LIKE'%T%'ESCAPE'T'以上表達(dá)式中使用了ESCAPE關(guān)鍵字定義了轉(zhuǎn)義字符“T”,這樣,T就成為轉(zhuǎn)義字符,將字符串“%T%”中的第二個(gè)百分符(%)作為實(shí)際值,而不是通配符。但是,第一個(gè)百分符“%”仍然被看做是通配符,因此滿足該查詢條件的字符串為所有以“%”結(jié)尾的字符串。
3)排序查詢結(jié)果
SELECT語(yǔ)句獲得的數(shù)據(jù)一般是沒(méi)有排序的(使用DISTINCT關(guān)鍵字除外)。在SQL語(yǔ)言中,使用ORDERBY子句對(duì)查詢的結(jié)果進(jìn)行排序?!窕九判颉狾RDERBY
ORDERBY子句可以指定在SELECT語(yǔ)句返回的列的順序。語(yǔ)法格式可表示如下:
ORDERBY表達(dá)式1[ASC|DESC][,表達(dá)式2[ASC|DESC][,…n]]其中,表達(dá)式是用于排序的列。該語(yǔ)句可用于多列排序,各列在OR
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 新小學(xué)數(shù)學(xué)六年級(jí)下冊(cè)《圓錐的體積》公開(kāi)課獲獎(jiǎng)百校聯(lián)賽教案
- 小學(xué)一年級(jí)語(yǔ)文教案中積累讀中感悟雪地里的小畫家教學(xué)設(shè)計(jì)及評(píng)點(diǎn)(2025-2026學(xué)年)
- 八年級(jí)上冊(cè)英語(yǔ)第八單元獲獎(jiǎng)?wù)f課比賽教案(2025-2026學(xué)年)
- 金融犯罪知識(shí)教案
- 幼兒園大班音樂(lè)菜場(chǎng)教案
- 高中數(shù)學(xué)空間直角坐標(biāo)系示范教案新人教A版必修
- 2026年證券分析師之發(fā)布證券研究報(bào)告業(yè)務(wù)考試題庫(kù)300道(模擬題)
- 交通安全分心駕駛課件
- 兒科護(hù)理實(shí)踐技能訓(xùn)練
- 垃圾壓縮站運(yùn)營(yíng)維護(hù)管理標(biāo)準(zhǔn)方案
- 《常見(jiàn)抗凝劑分類》課件
- 2025運(yùn)輸與配送期末考試題庫(kù)及答案
- 婦科TCT培訓(xùn)課件
- 婦科急癥培訓(xùn)課件
- 2025年灌溉與排水工程考試試題及答案
- 抵押權(quán)概述課件
- 軍事理論-綜合版(新版)知到智慧樹(shù)答案
- 護(hù)理禮儀情景劇課件模板
- 基因克隆技術(shù)課件教案
- 企業(yè)營(yíng)收管理辦法
評(píng)論
0/150
提交評(píng)論