數(shù)據(jù)庫技術(shù)1611B.ppt_第1頁
數(shù)據(jù)庫技術(shù)1611B.ppt_第2頁
數(shù)據(jù)庫技術(shù)1611B.ppt_第3頁
數(shù)據(jù)庫技術(shù)1611B.ppt_第4頁
數(shù)據(jù)庫技術(shù)1611B.ppt_第5頁
已閱讀5頁,還剩76頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、數(shù)據(jù)庫技術(shù),SQL Sever,數(shù)據(jù)庫簡介,用自定義文件格式保存數(shù)據(jù)的劣勢 DBMS(DataBase Management Stytem,數(shù)據(jù)庫管理系統(tǒng))和數(shù)據(jù)庫。平時談到“數(shù)據(jù)庫”可能有兩種含義:MSSQLSever、Oracle等某種DBMS:存放一堆數(shù)據(jù)表的一個分類( Catalog ) 不同品牌的DBMS有自己不同特點:MYSQL、MSSQLSever、DB2、Oracle、Access、Sybase等。對于開發(fā)人員來講,大同小異。 SQLSOLSever MSSQLSever最常見的錯誤。 除了Access、SQLSeverCE等文件型數(shù)據(jù)庫之外,大部分數(shù)據(jù)庫都需要數(shù)據(jù)庫服務(wù)器才能

2、運行。學習。開發(fā)時是廉價本機的數(shù)據(jù)庫,上線運行時是數(shù)據(jù)庫運行在單獨的服務(wù)器。,數(shù)據(jù)庫中的概念,Catalog(分類)(又叫數(shù)據(jù)庫DataBase、表空間TableSpace),不同類的數(shù)據(jù)應(yīng)該放在不同的數(shù)據(jù)庫中 1、便于對各個Catalog進行個性化管理 2、避免命名沖突 3、安全性更高 Table(表)書都放在書架上,碗都放在櫥柜中,不同類型的資料放在不同的格子中,將這種區(qū)域叫做表(Table),不同的表根據(jù)放的數(shù)據(jù)進行空間的優(yōu)化,找起來也方便。 列(Column) 字段(Field),主鍵(PrimaryKey),主鍵就是數(shù)據(jù)行的唯一標識。不會重復的列才能當主鍵。一個表可以沒有主鍵,但是會

3、非常難以處理,因此沒有特殊理由表都要設(shè)定主鍵。 主鍵有兩種選用策略:業(yè)務(wù)主鍵和邏輯主鍵。業(yè)務(wù)主鍵是使用有業(yè)務(wù)意義的字段做主鍵,比如身份證件、銀行賬號等;邏輯主鍵是使用沒有任何業(yè)務(wù)意義的字段做主鍵。因為很難保證業(yè)務(wù)主鍵不會重復(身份證號會重復)、不會變化(賬號升位),因此推薦用邏輯主鍵。,表間關(guān)聯(lián)、外鍵(ForeignKey),SQLSever 的管理,需要安裝SOLSever2005或者SOLSever2008,若要使用SOLSever管理工具進行開發(fā)還要安裝SQL Sever Massagement Studio,還可以使用Visual Studio進行管理。 使用免費的SQL SeverE

4、xpress版本,Express版本的服務(wù)器名稱SQLEXPRESS,對于開發(fā)人員來講和其他版式?jīng)]有區(qū)別。 SOLSever的兩種驗收方式:用戶名驗證和windows驗證,開發(fā)是用windows驗證就行。 開發(fā)人員關(guān)注點在開發(fā)上,而不是配置、備份等之上,那是DBA做的事情。 創(chuàng)建數(shù)據(jù)庫,創(chuàng)建表,設(shè)置主鍵。 常見字段類型:bit(可選值0、1)、datetime、int、varchar、nvarchar(可能含有中文用nvarchar) Varchar(50)、Varchar(MAX) Varchar、nvarchar和char(n)的區(qū)別:char(n)不足長度n的部分用空格填充。,SQL語句

5、入門,SQL語句是和DBSM“交談”專用的語句,不同DBMS都認SQL語法。 SQL語句中字符串用單引號。 SQL語句對大小寫不敏感的,不敏感指的是SQL關(guān)鍵字,字符串值還是敏感的。 創(chuàng)建表、刪除表不僅可以手工完成,還可以執(zhí)行SQL語句完成,在自動化部署、數(shù)據(jù)導入中用的很多,CREATE TABLE T_Penson(id int NOT NULL、Name nvarchar(50)、Age int NULL)、Drop table T_Penson1 簡單的insert語句。INSERT INTO T_Person(id,name,Age) values(1,Jim,20) (*) SQL主

6、要分DDL(數(shù)據(jù)定義語言)和DML(數(shù)據(jù)操作語言 )兩類。Create Table 、Drop Table等屬于DDL,Select、Insert等屬于DML,主鍵選擇,SQL Server中有兩種常用的主鍵數(shù)據(jù)類型:int(或bigint)+標識列(又稱自動增長字段);uniqueidentifier(又稱Guid 、UUID)。 用標識列實現(xiàn)字段自增可以避免并發(fā)等問題,不要開發(fā)人員控制自增,用標識列的字段在insert的時候不用指定主鍵的值 Guid算法是一種可以產(chǎn)生唯一標識的高效算法,它使用網(wǎng)卡MAC、地址、納秒級時間、芯片ID碼等算出來的,這樣保證每次生成的GUID永遠不會重復,無論是

7、同一個計算機上還是不同的計算機。在公元3400年以前的GUID與任何其他產(chǎn)生過的GUID都你不相同。 SQL Server中產(chǎn)生SQL Server的函數(shù)newid(),.Net中生成Guid的方法: Guid.New Guid(),返回是Guid類型。 (*)Int自增字段的優(yōu)點:占用空間小、無需開發(fā)人員干預、易讀;缺點:效率低;數(shù)據(jù)導入導出的時候很痛苦。 (*) Guid 的優(yōu)點:效率高、數(shù)據(jù)導入導出方便;缺點:占用空間大、比易讀。 業(yè)界主流傾向于使用Guid 。,數(shù)據(jù)插入,Insert語句可以省略表名后的列名,但是不推薦。 如果插入的行中有些字段中的值不確定,那么Insert的時候不指定

8、那些列即可。 可以給字段默認值,如果Guid類型主鍵的默認值設(shè)定為newid()就會自動生成,很少可以這么干。 主鍵:Insert into Person3(Name,Age) values(lily,38); insert into Person4(ld,Name,Age) values(newid(),lily,30);,數(shù)據(jù)更新,更新一個列:UPDATE T_Person Set Age=30 更新多個列: UPDATE T_Person Set Age=30,Name=tom 更新一部分數(shù)據(jù): UPDATE T_Person Set Age=30 where Name=tom,用whe

9、re 語句表示只更新Name是tom的行,注意SQL中等于判斷用單個=,而不是=。 Where中還可以使用復雜的邏輯判斷UPDATE T_Person Set Age=30 where Name=tomor Age、=、)等。,數(shù)據(jù)刪除,刪除表中全部數(shù)據(jù):DETELE FROM T_Person。 Delete只是刪除數(shù)據(jù),表還在,和Drop Table不同。 Delete也可以帶where子句來刪除已部分數(shù)據(jù): DETELE FROM T_Person WHERE Fage20.,數(shù)據(jù)檢索,執(zhí)行備注中的代碼創(chuàng)建測試數(shù)據(jù)表。 簡單的數(shù)據(jù)檢索:SELECT * FROM T-Employee。

10、只檢索需要的列:SELECT FNumber FROM T-Employee、 SELECT FName,F Age FROM T-Employee。 列別名: SELECT FNumber AS編號,Fname AS 姓名, FAge AS Age111 FROM T-Employee。 使用where檢索符合條件的數(shù)據(jù): SELECT FName FROM T-Employee WHERE Fsalary5000。.故事:新員工的數(shù)據(jù)檢索噩夢。 還可以就檢索不與任何飚關(guān)聯(lián)的數(shù)據(jù):select 1+1;select newid();sekect getdate();,數(shù)據(jù)檢索,Create

11、table T_Employee(FNumber varchar(20),FName varchar(20),FAge int,FSalary numeric(10,2),primary key (FNumber); Insert into T_Employee(FNumber,FName,FAge,FSalary) values(DEV001,Tom,25,8300); Insert into T_Employee(FNumber,FName,FAge,FSalary) values(DEV002,Jerry,28,2300.80); Insert into T_Employee(FNumb

12、er,FName,FAge,FSalary) values(SALES001,Joho,23,5000); Insert into T_Employee(FNumber,FName,FAge,FSalary) values(SALES002,Kerry,28,6200); Insert into T_Employee(FNumber,FName,FAge,FSalary) values(SALES003,Stone,22,1200); Insert into T_Employee(FNumber,FName,FAge,FSalary) values(HR001,Jane,23,2200.88)

13、; Insert into T_Employee(FNumber,FName,FAge,FSalary) values(HR002,Tina,25,5200.36); Insert into T_Employee(FNumber,FName,FAge,FSalary) values(IT001,Smith,28,3900); Insert into T_Employee(FNumber,FName,FAge,FSalary) values(IT002,Tom,27,2800);,數(shù)據(jù)匯總,SQL聚合函數(shù):MAX(最大值)、MIN(最小值)、AVG(平均值)、SUM(和)、COUNT(數(shù)量) 大

14、于25歲的員工的最高工資:SELECT MAX(FSalary) FROM T_Employee WHERE FAge25 最低工資和最高工資:SELECT MIN(FSalary).MAX(FSalary) FROM T_Employee,數(shù)據(jù)排序,ORDER BY子句位于SELECT語句的末尾,它允許指定按照一個列或者多個列進行排序, 還可以指定排序方式是升序(從小到大排列,ASC) 還是降序(從大到小排列,DESC)。 按照年齡升序排序所有員工信息的列表:SELECT * FROM T_Employee ORDER BY FAge DESC.FSalary DESC 按照年齡從大到小排序

15、,如果年齡相同則按照工資從大到小排序:SELECT * FROM T_Employee ORDER BY FAge DESE.FSalary DESC ORDER BY 字句要放在WHERE子句之后: SELECT * FROM T_Employee WHERE FAge32 ORDER BY FAge DESE.FSalary DESC,通配符過濾,使用通配符過濾使用關(guān)鍵字 like 單子符匹配的通配符為半角下劃線“_”,匹配單個出現(xiàn)的字符。 比如:查找以任意一個字符開頭,后面是“erry”的員工姓名。 多字符匹配的通配符為半角百分號“%”,匹配任意個數(shù)(0個或多個)任意字符。 K% 查找開

16、發(fā)部的所有人員,空值處理,數(shù)據(jù)庫中,一個列如果沒有指定的值,那么值就是Null,這個null和c#中的null不一樣,數(shù)據(jù)庫中的null表示的是“不知道”,而不是表沒有。 Null+1的結(jié)果還是null,因為“不知道”+1還是“不知道” Select * from T_Employee where Fname=null; Select * from T_Employee where Fnamenull; 都沒有返回結(jié)果,因為數(shù)據(jù)也“不知道” 在SQL中使用 is null,is not null來進行空值判斷: select * from T_Employee where FName is n

17、ull; select * from T_Employee where FName is not null;,多值匹配,離散值or 使用關(guān)鍵字In(值1,值2,值3.) select * from T_Employee WHERE FAge=28 OR FAge=25 OR FAge=23 select * from T_Employee WHERE FAge IN(23,25,28) 范圍and 使用關(guān)鍵字Between who and who select * from T_Employee where FAge=23and FAge=27 select * from T_Employee

18、 WHERE FAge BETWEEN 23 AND 27,數(shù)據(jù)分組,按照年齡進行分組統(tǒng)計個年齡段的人數(shù): Select fage,count(*) from T_Employee Group by fage; 錯誤 select fage as 年齡,FName ,COUNT(*) as 個數(shù) from T_Employee group by FAge; 錯誤提示:因為該列沒有包含在聚合函數(shù)或GROUP BY 子句中 列名,select后跟的東東要么是group by中的字段,要么是聚合函數(shù) SELECT fage,MAX(fsalary),COUNT(*)from T_Employee g

19、roup by FAge; Group by必須放在where條件之后。,Having語句,在where語句中能否使用聚合函數(shù)? 答:不能! 因為在where語句中不能否使用聚合函數(shù),因此使用having來過濾。 (having代替where進行過濾)使用聚合函數(shù)時! 練習 1,用fage進行分組,篩選出不同年齡員工的個數(shù),要求只顯示同一個年齡個數(shù)大于1的。 2,使用fage進行分組,篩選出不同年齡員工的個數(shù),只對工資大于2000的員工進行篩選。 Where寫在group by 之前, Having在group by之后。 having是對分組后的信息進行過濾,能用的字段和select中能用的

20、列一般是一樣的。 所以having不能代替where,限制結(jié)果集行數(shù),select top 3 * from T_Employee order by FSalary desc; 檢索按照工資高低排序,檢索從第4開始一共3個人的信息,select top 3 * from T_Employee where FNumber NOT IN(select top 3 FNumber from T_Employee order by FSalary DESC) order by FSalary desc; (*這個相對比較難理解,下學期還會講),MSSQLServer2005以上的版本,增加了Row_N

21、umber函數(shù)簡化實現(xiàn)分頁,.,去掉數(shù)據(jù)重復,Distinct是對整個結(jié)果集進行數(shù)據(jù)重復的處理,注意:不是針對某個列進行重復處理。 Select distinct 列名 from 表名,對數(shù)據(jù)表進行修改:-alter 添加字段:add 字段名 字段類型,. 課下文成對數(shù)據(jù)表的其他修改:刪除字段,刪除.,聯(lián)合結(jié)果集,UNION合并兩個查詢結(jié)果集,并且將其中完全一樣的若干條記錄合并為1條。,Union進行合并的時候,要進行計算,效率會比較低,因此我們可以設(shè)置(如果不確定是否需要合并的話)不合并重復的記錄。使用 Union all就可以做到!,作業(yè)3,1要求查詢員工的最低年齡和最高年齡,零時工和正式

22、工分別查詢,在合并。 2查詢每位正式員工員工的信息,包括工號,工資,并且在最后一行上顯示所有員工的工資和。,數(shù)值函數(shù)(*),ABS()求絕對值 Ceiling();舍入到最大整數(shù)。Ceiling-天花板 3.33,3.65,-3.98 Floor(),舍入到最小整數(shù)。3.61,-2.12 Floor-地面 round(),四舍五入,舍入到半徑最近的數(shù)。 Round(3.1415926) Round-半徑,字符串函數(shù)(*),Len()計算字符串長度,從右向左數(shù)char個數(shù),當遇到左邊最后一個為空格字符后,如其后沒有字符則停止計算字符個數(shù)(忽略字符右邊的空格) LTrim()去左邊空格, RTri

23、m()去右邊空格, LTrim(RTrim() 去兩邊空格; SUBSTRING(string,start_Position,Length) String原始字符串,start_Position字串在原始字串中的起始位置,字串的最大長度。,日期函數(shù),Getdate():取得當前日期; DateAdd(datePart,number,date):計算增加以后的日期。 參數(shù)datePart:要改變的單位(年,月,日,時,分,秒),number改變的數(shù)量,date改變的對象。 datePart可選值 Year yy,year Quarter qq,q Month mm,m Day ,dd,d Wee

24、k wk ww Hour hh Minute mm,m,日期函數(shù),Getdate():取得當前日期; DateAdd(datePart,number,date):計算增加以后的日期。 參數(shù)datePart:要改變的單位(年,月,日,時,分,秒),number改變的數(shù)量,date改變的對象。 datePart可選值 Year yy,year Quarter qq,q Month mm,m Day ,dd,d Week wk ww Hour hh Minute mm,m,日期函數(shù),Getdate():取得當前日期; DateAdd(datePart,number,date):計算增加以后的日期。

25、DATEdiff(datepart,startdate,enddate) datePart(datePart,date)返回一個日期的特定部分; 作業(yè)5: 1取出同一年入職的員工的個數(shù)。 2取出入職年數(shù)相同的員工的個數(shù)。(兩列,第一列入職了幾年,第二列人數(shù)),空值處理函數(shù),Isnull(expression,value):如果表達式的值不為空,函數(shù)返回值為expression的值,如果表達式的值為空返回value的值。 select isnull(Fname,N匿名)as N姓名 from T_Employee;,數(shù)據(jù)類型轉(zhuǎn)換函數(shù),Convert () xxxprase Cast(轉(zhuǎn)換的對象

26、as 轉(zhuǎn)換的標準,) Conver(轉(zhuǎn)換的對象,轉(zhuǎn)換的標準),CASE函數(shù),相當于C#中的swith case 單值判斷 Case expression When value1 then returnvalue1 When value2 then returnvalue2 When value3 then returnvalue3 Else returndefault end,CASE函數(shù),相當于C#中的swith case 單值判斷,select fname as N姓名, ( case FTYPE WHEN 1 THEN 普通客戶 when 2 then 會員 when 3 then vi

27、p else未知客戶類型 end ) as N客戶類型 from t_customer;,CASE函數(shù),相當于C#中的if else 還支持分段查詢,select fname as N姓名, ( case when FSalary=2000 and FSalary5000 then 中等收入 else 高收入 end )AS 收入水平 from T_Employee;,練習1,表中有三列A,B,C列,用SQL語句實習,當A列大于B列時,選擇A類否則選擇B列; 當B列大于C列時,選擇B列,否則選擇C列。 表名為 。T_lianxi1,練習1,表中有三列A,B,C列,用SQL語句實習,當A列大于B

28、列時,選擇A類否則選擇B列; 當B列大于C列時,選擇B列,否則選擇C列。 表名為 。T_lianxi1 Select ( Case When AB THEN A WHEN AB THEN C WHEN CB THEN B ELSE B END ) From t_lianxi1,練習2,單號 金額 RK1 10 RK2 20 RK3 -30 RK4 -10,單號 收入 支出 RK1 10 0 RK2 20 0 RK3 0 30 RK4 0 10,T_lianxi1,查詢T_lianxi1表的結(jié)果,Select fnumber as 單號, (case When famount0 then fam

29、ont Else 0 end )as收入, (case )as 支出 from t_lainxi1,練習3,Date name score 2008-8-8 拜仁 勝 2008-8-9 奇才 勝 2008-8-9 湖人 勝 2008-8-10 拜仁 負 2008-8-8 拜仁 負 2008-8-12 奇才 勝,name 勝 負 拜仁 1 2 湖人 1 0 奇才 2 0,Select fname as name, (case score When 勝 then 1 Else then 0 end )as 勝, ( (case score When 負 then 1 Else then 0 end

30、 )as負 from t_scores,練習4,-創(chuàng)建一張表T_Callers,記錄電話呼叫員的工作流水,記錄呼叫員編號、對方號碼、通話開始時間、通話結(jié)束時間。建表、插數(shù)據(jù)等最后都自己寫SQL語句。 -要求: 1) 輸出所有數(shù)據(jù)中通話時間最長的5條記錄。 2) 輸出所有數(shù)據(jù)中撥打長途號碼(對方號碼以0開頭)的總時長。 3) 輸出本月通話總時長最多的前三個呼叫員的編號。 4) 輸出本月?lián)艽螂娫挻螖?shù)最多的前三個呼叫員的編號。 5) 輸出所有數(shù)據(jù)的撥號流水,并且在最后一行添加總呼叫時長。 (記錄呼叫員編號、對方號碼、通話時長;匯總市內(nèi)號碼總時長長途號碼總時長) Id CallerNumber Tel

31、lNumber StartDateTime EndDateTime 1 001 02088888888 2010-7-10 10:01 2010-7-10 10:05 2 001 02088888888 2010-7-11 13:41 2010-7-11 13:52 3 001 89898989 2010-7-11 14:42 2010-7-11 14:49 4 002 02188368981 2010-7-13 21:04 2010-7-13 21:18 5 002 76767676 2010-6-29 20:15 2010-6-29 20:30 6 001 02288878243 2010

32、-7-15 13:40 2010-7-15 13:56 7 003 67254686 2010-7-13 11:06 2010-7-13 11:19 8 003 86231445 2010-6-19 19:19 2010-6-19 19:25 9 001 87422368 2010-6-19 19:25 2010-6-19 19:36 10 004 40045862245 2010-6-19 19:50 2010-6-19 19:59,練習4,Id CallerNumber TellNumber StartDateTime EndDateTime 1 001 02088888888 2010-

33、7-10 10:01 2010-7-10 10:05 2 001 02088888888 2010-7-11 13:41 2010-7-11 13:52 3 001 89898989 2010-7-11 14:42 2010-7-11 14:49 4 002 02188368981 2010-7-13 21:04 2010-7-13 21:18 5 002 76767676 2010-6-29 20:15 2010-6-29 20:30 6 001 02288878243 2010-7-15 13:40 2010-7-15 13:56 7 003 67254686 2010-7-13 11:0

34、6 2010-7-13 11:19 8 003 86231445 2010-6-19 19:19 2010-6-19 19:25 9 001 87422368 2010-6-19 19:25 2010-6-19 19:36 10 004 40045862245 2010-6-19 19:50 2010-6-19 19:59,Index索引,-創(chuàng)建一張表T_Callers,記錄電話呼叫員的工作流水,記錄呼叫員編號、對方號碼、通話開始時間、通話結(jié)束時間。建表、插數(shù)據(jù)等最后都自己寫SQL語句。 -要求: 1) 輸出所有數(shù)據(jù)中通話時間最長的5條記錄。 2) 輸出所有數(shù)據(jù)中撥打長途號碼(對方號碼以0開頭

35、)的總時長。 3) 輸出本月通話總時長最多的前三個呼叫員的編號。 4) 輸出本月?lián)艽螂娫挻螖?shù)最多的前三個呼叫員的編號。 5) 輸出所有數(shù)據(jù)的撥號流水,并且在最后一行添加總呼叫時長。 (記錄呼叫員編號、對方號碼、通話時長;匯總市內(nèi)號碼總時長長途號碼總時長) Id CallerNumber TellNumber StartDateTime EndDateTime 1 001 02088888888 2010-7-10 10:01 2010-7-10 10:05 2 001 02088888888 2010-7-11 13:41 2010-7-11 13:52 3 001 89898989 2010

36、-7-11 14:42 2010-7-11 14:49 4 002 02188368981 2010-7-13 21:04 2010-7-13 21:18 5 002 76767676 2010-6-29 20:15 2010-6-29 20:30 6 001 02288878243 2010-7-15 13:40 2010-7-15 13:56 7 003 67254686 2010-7-13 11:06 2010-7-13 11:19 8 003 86231445 2010-6-19 19:19 2010-6-19 19:25 9 001 87422368 2010-6-19 19:25

37、2010-6-19 19:36 10 004 40045862245 2010-6-19 19:50 2010-6-19 19:59,復習,1、新建數(shù)據(jù)庫MyDB611,- 2、新建數(shù)據(jù)表T_Order; Create ,刪除 dorp,修改alter DDL: 新建數(shù)據(jù)表:Create Table T_Order (FId int not null, FNumber varchar(20) not null,FPrice numeric(10,2) not null,FCumsterId int ,FTypeId int null,primary key(FId) 刪除 drop table

38、 T_Order; 修改添加字段 alter table t_Order add FName varchar(20) not null; 修改刪除字段: alter table t_order drop column FName ;,FName,復習,1、新建數(shù)據(jù)庫MyDB611,- 2、新建數(shù)據(jù)表T_Order; Create ,刪除 dorp,修改alter DML: 插入數(shù)據(jù): insert into T_Order (FId,FNumber,FPrice,FCumsterId,FTypeId) Values(1,K001,100.00,1,1); insert into T_Order

39、 (FId,FNumber,FPrice,FCumsterId,FTypeId) Values(2,K002,200.00,1,1); 刪除表內(nèi)容:Delete from 表名 刪除所有表的內(nèi)容 delete from 表名 where 條件 :刪除符合條件的某幾條記錄 修改表內(nèi)容:update who(表名) set who(字段名)=something where 條件(那些記錄的這個字段的值變。) 查詢:select 哪些字段(字段名羅列,所有字段用*) from 表名 where 篩選條件,FName,Index索引,如果我們?yōu)槟挲g列創(chuàng)建一個索引,注意這里的索引所采用的值是排序的:,假

40、如我們要查找年齡為 13 歲的所有人員,那么可以掃描索引,結(jié)果得出前 3 行,當?shù)竭_年齡為 14 的行的時候,我們發(fā)現(xiàn)它是一個比我們正在查找的年齡要大的人員。索引值是排序的,因此在讀到包含 14 的記錄時,我們知道不會再有匹配的記錄,可以退出了。 如果查找一個值,它在索引表中某個中間點以前不會出現(xiàn),那么也有找到其第一個匹配索引項的定位算法,而不用進行表的順序掃描(如二分查找法)。這樣,可以快速定位到第一個匹配的值,以節(jié)省大量搜索時間。,Join- inner join,-建立一個客戶表 createtableT_Customers( idintnotnull, name nvarchar(50

41、)collatechinese_prc_ci_asnull, ageintnull ); -建立一個訂單表 createtableT_Orders( idintnotnull, billno nvarchar(50)collatechinese_prc_ci_asnull, customeridintnull); 使用join 可以使兩個具有練習的表連接起來進行查詢: Select 表1.字段名,表2.字段名 From 表1 inner join 表2 on 表1.字段=表2.字段,Join,1 INNER JOIN 2 LEFT JOIN 3 RIGHT JOIN 4 CROSS JOIN,

42、前面所學的 SQL 知識,我們僅能夠從一張數(shù)據(jù)表中檢索數(shù)據(jù),這在很多情 況下是不能滿足要求的,因為經(jīng)常需要從多個表中進行檢索才能得到想要的數(shù)據(jù),SQL 中的“表連接”就是用來解決這個問題的。表連接使用 JOIN 關(guān)鍵字將一個或者多個表按照彼此間的關(guān)系連接為一個結(jié)果集。 表連接在 SQL 中的地位是非常重要的。假設(shè)需要查找姓名為 MIKE 的客戶的訂單號和票價。如果 SQL 不支持表連接,那么完成這個功能的第一個任務(wù)將是在 T_Customer 表中檢索姓名為 MIKE 的客戶的 FId 值怎么辦呢?,Join,表連接在 SQL 中的地位是非常重要的。假設(shè)需要查找姓名為 MIKE 的客戶的訂單號

43、和票價。如果 SQL 不支持表連接,那么完成這個功能的第一個任務(wù)將是在 T_Customer 表中檢索姓名為 MIKE 的客戶的 FId 值:,SELECT FId FROM T_Customer WHERE FName=MIKE 這個 SQL 語句返回 2 ,也就是姓名為 MIKE 的客戶的 FId 值為 2,這樣就可以到 T_Order中檢索 FCustomerId 等于 2 的記錄: SELECT FNumber,FPrice FROM T_Order WHERE FCustomerId=2,-建立一個客戶表 CREATE TABLE T_Customer (FId INT NOT NU

44、LL ,FName VARCHAR(20) NOT NULL , FAge INT,PRIMARY KEY (FId) -建立一個訂單種類表 CREATE TABLE T_OrderType (FId INT NOT NULL ,FName VARCHAR(20) NOT NULL, PRIMARY KEY (FId) -建立一個訂單表 CREATE TABLE T_Order (FId INT NOT NULL ,FNumber VARCHAR(20) NOT NULL , FPrice NUMERIC(10,2),FCustomerId INT, FTypeId INT,PRIMARY K

45、EY (FId),Join,表連接在 SQL 中的地位是非常重要的。假設(shè)需要查找姓名為 MIKE 的客戶的訂單號和票價。如果 SQL 不支持表連接,那么完成這個功能的第一個任務(wù)將是在 T_Customer 表中檢索姓名為 MIKE 的客戶的 FId 值:,SELECT FId FROM T_Customer WHERE FName=MIKE 這個 SQL 語句返回 2 ,也就是姓名為 MIKE 的客戶的 FId 值為 2,這樣就可以到 T_Order中檢索 FCustomerId 等于 2 的記錄: SELECT FNumber,FPrice FROM T_Order WHERE FCusto

46、merId=2,Join,表連接就像連接兩張數(shù)據(jù)表的連線,線的兩端是分別在兩張表的特定字段上的。在這里的例子中 T_Customer 表的 FId 字段和 T_Order 表的 FCustomerId 字段就是關(guān)聯(lián)關(guān)系的兩個端點。在使用表連接的時候必須顯式的指定這個關(guān)聯(lián)關(guān)系。,1 內(nèi)連接(INNER JOIN) 內(nèi)連接組合兩張表,并且基于兩張表中的關(guān)聯(lián)關(guān)系來連接它們。使用內(nèi)連接需要指定表中哪些字段組成關(guān)聯(lián)關(guān)系,并且需要指定基于什么條件進行連接。內(nèi)連接的語法如下: INNER JOIN table_name ON condition 其中 table_name 為被關(guān)聯(lián)的表名,condition

47、 則為進行連接時的條件。 下面的 SQL 語句檢索所有的客戶姓名為 MIKE 的客戶的訂單號以及訂單價格: SELECT FNumber,FPrice FROM T_Order INNER JOIN T_Customer ON FCustomerId= T_Customer.FId WHERE T_Customer.FName=TOM,Join,在使用表連接的時候可以不局限于只連接兩張表,因為有很多情況下需要聯(lián)系許多表。 例如,我們需要檢索每張訂單的訂單號、價格、客戶姓名、訂單類型等信息,由于客戶信息和訂單類型信息是保存在另外的表中的,因此需要同時連接T_Customer 和 T_OrderT

48、ype兩張表才能檢索到所需要的信息,編寫如下 SQL 語句即可:,select o.FNumber,o.FPrice,c.FName,c.FAge,ot.FName from T_Order as o join T_Customer as c on o.FCustomerId=c.FId join T_OrderType as ot ON o.FtypeID=ot.FId;,Join,2 不等值連接 以上這些都是等值連接,也就是在這種連接的ON子句的條件包含一個等號運算。 等值連接是最常用的連接,因為它指定的連接條件是一個表中的一個字段必須等于另一個表中的一個字段。 另外一種不等值連接,也就是

49、在連接的條件中可以使用小于()、不等于()等運算符,而且還可以使用LIKE、BETWEEN AND等運算符,甚至還可以使用函數(shù)。 例如,如果需要檢索價格小于每個客戶的年齡的五倍值的訂單列表,那么就可以使用不等值連接,實現(xiàn)的SQL語句如下所示: SELECT T_Order.FNumber,T_Order.FPrice, T_Customer.FName,T_Customer.FAge FROM T_Order INNER JOIN T_Customer ON T_Order.FPrice T_Customer.FAge*5,Join,不等值連接產(chǎn)生了大量的查詢結(jié)果,因為它是對被連接的兩張表做了

50、笛卡爾運算,所以如果只想查看與客戶對應(yīng)的訂單,那么就要在不等值連接后添加等值連接匹配條件。實現(xiàn)的SQL語句如下: SELECT T_Order.FNumber,T_Order.FPrice,T_Customer.FName,T_Customer.FAge FROM T_Order INNER JOIN T_Customer ON T_Order.FPrice T_Customer.FAge*5 and T_Order.FCustomerId=T_Customer.Fid 這里添加了“ and T_Order.FCustomerId=T_Customer.FId ”這個條件來限制匹配規(guī)則。,Jo

51、in,3 交叉連接 與內(nèi)連接比起來,交叉連接非常簡單,因為它不存在ON子句。交叉連接會將涉及到的所有表中的所有記錄都包含在結(jié)果集中??梢圆捎脙煞N方式來定義交叉連接,分別是隱式的和顯式的。 隱式的連接只要在SELECT語句的FROM語句后將要進行交叉連接的表名列出即可,這種方式可以被幾乎任意數(shù)據(jù)庫系統(tǒng)支持。 比如將 T_Customer 表和T_Order 做交叉連接: SELECT T_Customer.FId, T_Customer.FName, T_Customer.FAge, T_Order.FId, T_Order.FNumber, T_Order.FPrice FROM T_Cust

52、omer, T_Order,在交叉連接中同樣可以對表使用別名,比如上面的SQL語句來代替: SELECT c.FId, c.FName, c.FAge, o.FId, o.FNumber, o.FPrice FROM T_Customer AS c, T_Order AS o,Join,3 交叉連接 交叉連接的顯式定義方式為使用CROSS JOIN關(guān)鍵字,其語法與INNER JOIN類似, 下面的SQL將 T_Customer 表和 T_Order 做交叉連接: SELECT T_Customer.FId, T_Customer.FName, T_Customer.FAge, T_Order.

53、FId, T_Order.FNumber, T_Order.FPrice FROM T_Customer CROSS JOIN T_Order,使用CROSS JOIN的方式聲明的交叉連接只能被MYSQL、MSSQLServer和Oracle所支持,在DB2中是不被支持的。因為所有的數(shù)據(jù)庫系統(tǒng)都支持隱式的交叉連接,所以它是執(zhí)行 交叉連接的最好方法。,Join,自連接 目前為止,我們講解的連接都是在不同的數(shù)據(jù)表之間進行的,其實參與連接的表完全可以是同一表,也就是表與其自身相連接,這樣連接就被稱為自連接。 自連接并不是獨立于交叉連接、內(nèi)連接、外連接等這些連接方式之外的另外一種連接方式,而只是這些連

54、接方式的一種特例,也就是交叉連接、內(nèi)連接、外連接等連接方式中只要參與連接的表是同一張表,那么它們就可以被稱為自連接。 雖然大部分時間使用連接都是在連接不同的表,但是有的時候表也需要與自身連接,其主要用途就是檢索一張表內(nèi)部的匹配情況。 假設(shè)需要檢索與另外一個訂單的訂單類型一樣的所有訂單的列表。,?SELECT FNumber,FPrice,FTypeId FROM T_Order WHERE FTypeId= FTypeId,Join,如果要實現(xiàn)要求的功能,可以假象存在另外一個與 T_Order 表完全相同的表,這樣我們就可以在這兩個表之間進行任意的連接操作了。 套用INNER JOIN的寫法,

55、只是將參與連接的兩個表名都設(shè)置為 T_Order , SQL 語句如下: SELECT FNumber,FPrice,FTypeId FROM T_Order INNER JOIN T_Order ON T_Order.FTypeId=T_Order.FTypeId 這句 SQL 語句執(zhí)行以后數(shù)據(jù)庫系統(tǒng)會報出如下的錯誤信息: FROM 子句中的對象 “T_Order” 和 “T_Order” 具有相同的表現(xiàn)名稱。請使用相關(guān)名稱來區(qū)分它們。 SELECT o1.FNumber,o1.FPrice,o1.FTypeId, 02.FNumber,o2.FPrice,o2.FTypeId FROM T

56、_Order as o1 INNER JOIN T_Order as o2 ON o1.FTypeId=o2.FTypeId 這里為 T_Order 表取了兩個別名o1和o2,并且在引用表中列的時候也明確的指定了列屬于那個表下的,這樣數(shù)據(jù)庫系統(tǒng)就能區(qū)分這兩個別名代表的表了。使用別名以后我們可以將這兩個別名看作結(jié)構(gòu)相同、數(shù)據(jù)相同的兩個不同的表,這樣就可以避免思維上的障礙。,Join,這個SQL語句執(zhí)行成功,沒有語法錯誤,它是一個有效的自連接,不過它執(zhí)行所產(chǎn)生的結(jié)果卻不是正確的。比如第一行中“訂單號為K001的訂單與訂單號為K001的訂單的訂單類型相同”,自己的訂單類型當然與自己相同,這當然是正確

57、的,可是這樣的結(jié)果對我們來說是沒有意義的。ON子句中指定兩個表的FTypeId字段必須相同,當然對于同一個訂單來說,它們肯定是相同的,而這里真正要查詢的是具有相同的FTypeId字段值的兩個不同的訂單,因此需要在連接條件中添加一個新的條件,修改后的SQL語句如下: SELECT o1.FNumber,o1.FPrice,o1.FTypeId, o2.FNumber,o2.FPrice,o2.FTypeId FROM T_Order o1 INNER JOIN T_Order o2 ON o1.FTypeId=o2.FTypeId and o1.FIdo2.FId ON 子句末端添加的新條件“

58、and o1.FIdo2.FId ”檢查了別名為 o1 的表的主鍵不等于名為 o2 的表的主鍵,因為主鍵是唯一的,所以這樣就可以確保得到的是一個不同的訂單,從而不包含同一張訂單。,Join,這個SQL語句執(zhí)行成功,沒有語法錯誤,它是一個有效的自連接,不過它執(zhí)行所產(chǎn)生的結(jié)果卻不是正確的。比如第一行中“訂單號為K001的訂單與訂單號為K001的訂單的訂單類型相同”,自己的訂單類型當然與自己相同,這當然是正確的,可是這樣的結(jié)果對我們來說是沒有意義的。ON子句中指定兩個表的FTypeId字段必須相同,當然對于同一個訂單來說,它們肯定是相同的,而這里真正要查詢的是具有相同的FTypeId字段值的兩個不同的訂單,因此需要在連接條件中添加一個新的條件,修改后的SQL語句如下: SELECT o

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論