建站技術網專注分享網站建設技術,網站建設教程,真正幫你學會做網站技術,輕松解決網站建設過程中遇到的常見問題,為廣大站長服務。 網站地圖 | 收藏本站 | 訂閱
域名投資,就來找米網,認準網址:www.zhaomi.cc 專業仿站,就到仿站網:www.fangzhan.org
  站內公告: ·帝國cms教程內容已更新,歡迎關注     ·建站技術網采用阿里云服務器,備案已通    
您當前的位置:建站技術網 > 數據庫教程 > SQLserver教程

SQL SERVER 基礎篇(一):知識點、SQL語句學習及詳細總結

時間:2018-02-02 16:11:40  來源:網絡收集  整理: 建站技術網 www.txwlqq.com     點擊:17次

sql server詳細的基礎總結,可先點開CSDN自帶的博客目錄看看大體結構~



一. 數據庫簡介和創建

1. 系統數據庫

在安裝好SQL SERVER后,系統會自動安裝5個用于維護系統正常運行的系統數據庫: 
(1)master:記錄了SQL SERVER實例的所有系統級消息,包括實例范圍的元數據(如登錄帳號)、端點、鏈接服務器和系統配置設置。 
(2)msdb:供SQL SERVER 代理服務調度報警和作業以及記錄操作員的使用,保存關于調度報警、作業、操作員等信息。(備份還原時) 
(3)model:SQL SERVER 實例上創建的所有數據庫的模板。 
(4)tempdb:臨時數據庫,用于保存臨時對象或中間結果集,為數據庫的排列等操作提供一個臨時工作空間。(每次啟動都會重新創建) 
(5)Resource:一個只讀數據庫,包含了SQL SERVER 的所有系統對象。(隱藏的數據庫)


2. 數據庫的組成

2.1 數據文件 
(1)主要數據文件:擴展名為 .mdf ,每個數據庫有且只能有一個。 
(2)次要數據文件:擴展名為 .ndf , 可以沒有或有多個。

2.2 日志文件 
擴展名為 .ldf ,用于存放恢復數據庫的所有日志信息。

2.3 數據的存儲分配 
(1)數據文件和日志文件的默認存放位置為:\Programe Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data文件夾。 
(2)數據的存儲分配單位是數據頁。一頁表是一塊8KB的連續磁盤空間。 
(3)頁是存儲數據的最小空間分配單位,頁的大小決定了數據庫表中一行數據的最大大小。


3. SQL語句 數據庫操作

(1)創建數據庫

CREATE  DATABASE database_name





二. SQL基礎

SQL(Structured Query Language,結構化查詢語言)是用戶操作關系數據庫的通用語言。

1. SQL功能概述

這里寫圖片描述


2. 系統提供的數據類型

2.1 數值數據類型

數據類型說明存儲空間
bitbit數據類型是整型,其值只能是0、1或空值。這種數據類型用于存儲只有兩種可能值的數據,如Yes 或No、True 或False 、On 或Off. (很省空間的一種數據類型,如果能夠滿足需求應該盡量多用。)1字節
tinyinttinyint 數據類型能存儲從0到255 之間的整數。它在你只打算存儲有限數目的數值時很有用。1字節
smallintsmallint 數據類型可以存儲從- 2的15次冪(-32768)到2的15次冪(32767)之間的整數。這種數據類型對存儲一些常限定在特定范圍內的數值型數據非常有用。(如果tinyint類型太單調不能滿足您的需求,您可以考慮用smallint類型,因為這個類型相對也是比較安全的,不接受惡意腳本內容的嵌入。)2字節
intint 數據類型可以存儲從- 2的31次冪(-2147483648)到2的31次冪 (2147483 647)之間的整數。存儲到數據庫的幾乎所有數值型的數據都可以用這種數據類型4個字節
numeric(p,s) 或 decimal(p,s)數據類型能用來存儲從-10的38次冪-1到10的38次冪-1的固定精度和范圍的數值型數據。使用這種數據類型時,必須指定范圍和精度。 范圍是小數點左右所能存儲的數字的總位數。精度是小數點右邊存儲的數字的位數最多17個字節

2.2 普通編碼字符串類型

數據類型說明存儲空間
char(n)char數據類型用來存儲指定長度的定長非統一編碼型的數據,n表示字符串的最大長度,取值范圍為1~8000 (若實際字符串控件小于n,系統自動在后面補空格)n字節_______
varchar(n)可變長度的字符串類型,n表示字符串的最大長度,取值范圍為1~8000。字符數+2字節額外開銷
texttext 數據類型用來存儲大量的非統一編碼型字符數據。這種數據類型最多可以有231-1或20億個字符.每個字符一個字節

char 和 varchar的區別: 
若某列數據類型為varchar(20),存字符串”Jone”時,只占用4個字節,而char(20)會在為填滿的空間中填寫空格。所以, varchar類型比char類型更節省空間,但它的開銷會大一些,處理速度也慢一些。因此,n值比較。ㄐ∮4),用char類型更好些。


2.3 統一編碼字符串類型(Unicode)

數據類型說明存儲空間
nchar(n)nchar 數據類型用來存儲定長統一編碼字符型數據。統一編碼用雙字節結構來存儲每個字符,而不是用單字節(普通文本中的情況)。它允許大量的擴展字符。此數據類型能存儲4000種字符,使用的字節空間上增加了一倍.2n字節_______
nvarchar(n)nvarchar 數據類型用作變長的統一編碼字符型數據。此數據類型能存儲4000種字符,使用的字節空間增加了一倍.字符數+2字節額外開銷
ntext最多可存儲2的30次方-1將近10億個字符每個字符兩個字節





三. SQL數據操作語言

1.數據查詢語句

1.1 查詢語句的基本結構

SELECT <目標列名序列>  --需要哪些列    From <表名>      --來自哪張表
    [WHERE <行選擇條件>]
    [GROUP BY <分組依據列>]
    [HAVING <組>]
    [ORDER BY <排序依據列>]123456

SELECT子句用于指定輸出的字段; 
FROM子句用于指定數據的來源; 
WHERE子句用于指定數據的選擇條件; 
GROUP BY子句用于對檢索到的記錄進行分組; 
HAVING 子句用于指定組的選擇條件; 
ORDER BY 子句用于對查詢的結果進行排序; 
以上子句中,SELECT 子句和FROM子句是必需的,其它是可選的。



1.2 單表查詢

1.2.1選擇表中若干列

(1)查詢指定的列

SELECT 列名 FROM 表名1

例子 :SELECT Sname,Sno FROM Student

(2)查詢全部列

SELECT * FROM 表名1

例子 :SELECT * FROM Student

(3)查詢經過計算的列

SELECT 列名 FROM 表名1

例子 :SELECT Sname,year(getdata()) - year(Birthdate) FROM Student




1.2.2 選擇表中的若干元祖

(1)消除取值相同的行:DISTINCT

SELECT DISTINCT Sno FROM 表名1

例子 :SELECT DISTINCT Sno FROM Student



(2)查詢滿足條件的元祖

查詢條件謂 詞
比較=、>、>=、<=、<、<>、!=、!>、!<
確定范圍BETWEEN…AND、 NOT BETWEEN…AND
確定集合IN 、NOT IN
字符匹配LIKE 、NOT LIKE
空值IS NULL、IS NOT NULL
多重條件(邏輯謂詞)AND、OR

a.比較大小 
例子 :SELECT Sname FROM Student WHERE year(getdata()) - year(Birthdate) < 20


b.確定范圍 
BETWEEN…AND 和 NOT BETWEEN…AND可用于查找屬性值在或不在指定范圍。

列名 | 表達式 | [NOT] BETWEEN 下限值 AND 上限值  1

BETWEEN…AND 代表的范圍是上限值和下限值之間(包括邊界值),即為 true。 
NOT BETWEEN…AND 代表的范圍是不在上限值和下限值之間(不包括邊界值),即為true。(若判斷值為邊界值時,為 false)

例子 :SELECT Sno,Cno FROM SC WHERE Grade BETWEEN 80 AND 90 
此查詢等價于:SELECT Sno,Cno FROM SC WHERE Grade >= 80 AND Grade <= 90

例子 :SELECT Sno,Cno FROM SC WHERE Grade NOT BETWEEN 80 AND 90 
此查詢等價于:SELECT Sno,Cno FROM SC WHERE Grade < 80 OR Grade > 90


c. 確定集合 
IN運算符的含義:當列中的值和集合中的某個常量值相等時,結果為True。 
NOT IN運算符的含義:當列中的值和集合中的全部常量值都不相等時,結果為True。

例子 :SELECT Sno FROM Student WHERE Dept IN ('信息管理系','計算機系') 
此查詢等價于:SELECT Sno FROM Student WHERE Dept = '信息管理系' OR Dept = '計算機系')

例子 :SELECT Sno FROM Student WHERE Dept NOT IN ('信息管理系','計算機系') 
此查詢等價于:SELECT Sno FROM Student WHERE Dept != '信息管理系' AND Dept != '計算機系')


d. 字符串匹配 
Like運算符用于查找指定列中與匹配串匹配的元祖。

列名 [NOT] LIKE <匹配串>1
通配符含義
_(下劃線)匹配任意一個字符
%(百分號)匹配0個或多個字符
[]匹配[]中的任意一個字符。如[abcd]表示匹配abcd其中任何一個,若是連續的,可以用 - 表示,如[a-d]
[^]不匹配[]中的任意一個字符。如[^abcd]表示不匹配abcd其中任何一個,若是連續的,可以用 - 表示,如[^a-d]

例子 :

(查詢姓“張”的學生詳細信息)SELECT * FROM Student WHERE Sname LIKE '張%'(查詢不姓“張”的學生詳細信息)SELECT * FROM Student WHERE Sname NOT LIKE '張%'(查詢姓“張”、“李”的學生詳細信息)SELECT * FROM Student WHERE Sname LIKE '[張李]%'(查詢名字的第二個字為“小” 或 “大”的學生詳細信息)SELECT * FROM Student WHERE Sname LIKE '_[小大]%'1234567891011

e. 涉及空值的查詢 
空值(NULL)在數據庫中有特殊含義,表示當前不確定或未知的值。判斷是否為NULL時,不可用普通的比較運算符,需用IS NULL 
例子 :SELECT Sno FROM Student WHERE Grade IS NULL



1.2.3 對查詢結果進行排序

將查詢結果按照指定的順序顯示。ASC表示按列值升序排列(從上往下,值從大到。。DESC表示按列值降序排列(從上往下,值從小到大)。默認為ASC。

ORDER BY <列名> [ASC|DESC]1

例子 :SELECT Sno,Grade FROM SC ORDER BY Grade DESC



1.2.4 使用聚合函數統計數據

聚合函數也稱為統計函數或集合函數,作用是對一組值進行計算并返回一個統計結果。

聚合函數含義
COUNT(*)統計表中元祖的個數
COUNT([DISTINCT]<列名>)統計本列的非空列值個數
SUM(<列名>)計算列值的和值(必須是數值型列)
AVG(<列名>)計算列值的平均值(必須是數值型列)
MAX(<列名>)計算列值的最大值
MIN(<列名>)計算列值的最小值

上述函數除 COUNT(*) 外,其它函數在計算過程中均忽略NULL值

(統計學生總人數)SELECT COUNT(*) FROM Student

(統計“001”學號學生的考試平均成績)SELECT AVG(Grade) FROM SC WHERE Sno = '001'(查詢“C001”號課程考試成績的最高分和最低分)SELECT MAX(Grade) 最高分,MIN(Grade) 最低分 FROM SC WHERE Cno = 'C001'12345678

聚合函數不能出現在WHERE子句中!



1.2.5 對數據進行分組統計

需要先對數據進行分組,然后再對每個組進行統計。分組子句GROUP BY。在一個查詢語句中,可以用多個列進行分組。 
分組子句跟在WHERE子句的后面:

GROUP BY <分組依據列>[,...n]
    [HAVING <組篩選條件>]12

(1)使用GROUP BY 子句

(統計每門課程的選課人數,列出課程號和選課人數)SELECT Cno as 課程號, COUNT(Sno) as 選課人數 From SC Group BY Cno

(統計每個學生的選課門數和平均成績)SELECT Sno 學號, COUNT(*)  選課門數,AVG(Grade) 平均成績 From SC Group BY Sno

帶WHERE子句的分組(統計每個系的女生人數)
SELECT Dept, COUNT(*)  女生人數 From Student Where Sex = '女' Group BY Dept12345678

(2)使用HAVING 子句 
HAVING子句用于對分組后的統計結果再進行篩選,它的功能與WHERE子句類似,它用于組而不是單個記錄。在HAVING子句中可以使用聚合函數,但在WHERE子句中不能,通常與GROUP子句一起使用。

(查詢選課門數超過3門的學生的學號和選課門數)SELECT Sno 學號, COUNT(*)  選課門數,AVG(Grade) 平均成績 From SC Group BY Sno HAVING COUNT(*) > 312

(3)WHERE 、GROUP BY 、HAVING 的作用及執行順序

  • WHERE子句用于篩選FROM子句中指定的數據所產生的行數據。

  • GROUP BY 子句用于對經 WHERE 子句篩選后的結果數據進行分組。

  • HAVING 子句用于對分組后的統計結果再進行篩選。

可以分組操作之前應用的篩選條件,在WHERE子句中指定它們更有效,這樣可以減少參與分組的數據行。在HAVING子句中指定的篩選條件應該是那些必須在執行分組操作之后應用的篩選條件。

(查詢計算機系和信息管理系每個系的學生人數)
第一種:SELECT Dept,COUNT(*) FROM Student GROUP BY Dept Having Dept in('計算機系','信息管理系')
第二種:SELECT Dept,COUNT(*) FROM Student WHERE Dept in ('計算機系','信息管理系')GROUP BY Dept 
123456

以上例子比較:第一種是按照系分組好了之后,只采取所有系中的兩個系,顯然效率不高。而第二種是先進行WHERE篩選條件之后,再進行GROUP BY 計算,顯示更好。





1.3 多表連接查詢

若一個查詢同時涉及到兩張或以上的表,則稱為連接查詢。

1.3.1 內連接

使用內連接時,如果兩個表的相關字段滿足條件,則從兩個表中提取數據組成新的記錄。

FROM 表1 [INNER] JOIN 表2 ON <連接條件>1

注意:連接條件中的連接字段必須是可比的,必須是語義相同的列。

(查詢學生及選課的詳細信息)SELECT * FROM Student INNER JOIN SC ON Student.Sno = SC.Sno

(查詢計算機系學生的選課情況,列出該學生的名字、所修課程號、成績)------行選擇條件SELECT Sname,Cno,Grade FROM Student INNER JOIN SC ON Student.Sno = SC.Sno WHERE Dept = '計算機系'(統計每個系的平均成績) ------分組的多表查詢SELECT Dept,AVG(Grade) AS AverageGrade FROM Student S INNER JOIN SC ON S.Sno = SC.Sno Group BY Dept

(統計計算機系每個學生的選課門數、平均成績、最高成績、最低成績)------分組和行選擇條件的多表連接查詢SELECT Sno,COUNT(*),AVG(Grade),MAX(Grade),MIN(Grade) FROM Student S JOIN SC ON S.Sno = SC.Sno WHERE Dept = '計算機系' Group BY Dept1234567891011

1.3.2 自連接

自連接是一種特殊的內連接,相互連接的表在物理上是一張表,但在邏輯上可以看做是兩張表。

FROM 表1 AS T1 JOIN 表1 AS T21

通過為表取別名的方法,可以讓物理上的一張表在邏輯上成為兩張表。(一定要為表取別名。

(查詢與劉晨在同一個系學習的學生的姓名、所在系)SELECT S1.Sname,S1.Dept FROM Student S1 JOIN Student S2 
ON S1.Dept = S2.Dept   ---同一個系的學生WHERE S2.Sname = '劉晨'  ---S2表作為查詢條件AND S1.Sname != '劉晨'   ----S1表作為結果表,并從中去掉‘劉晨’本人信息12345

1.3.3 外連接

內連接操作中,只有滿足條件的元祖才能出現在查詢結果集中。 
外連接是只限制一張表中的數據必須滿足條件,而另一張表的數據可以不滿足條件。

FROM 表1 LEFT|RIGHT [OUTER] JOIN 表2 ON <連接條件>1

LEFT [OUTER] JOIN 稱為左外連接,含義是限制表2中的數據必須滿足條件,但不管表1中的數據是否滿足條件,均輸出表1中的數據。 
LEFT [OUTER] JOIN 稱為右外連接,含義是限制表1中的數據必須滿足條件,但不管表2中的數據是否滿足條件,均輸出表2中的數據。


內連接與外連接的區別: 
這里寫圖片描述

內連接:表A與表B進行內連接,則結果為兩個表中滿足條件的記錄集,即C部分。 
外連接:如果表A和表B進行左外連接,則結果為 記錄集A + 記錄集C;如果表A和表B進行右外連接,則結果為 記錄集B + 記錄集C。

(查詢沒有人選的選修課程名)SELECT Cname FROM Course C LEFT JOIN  SC ON C.Cno = SC.Cno WHERE SC.Cno IS NULL12

例子解析:如果存在部分課程為被人選擇,則必定在Course表中有但在SC表中沒有出現,即在進行外連接時沒人選的課程在與SC表構成的連接結果集中,對應的Sno、Cno、Grade列必定為空,所以只需**在連接后的結果中選出**SC表中Sno或Cno為空的元祖即可。

(統計計算機系每個學生的選課門數,包括沒選課的學生)SELECT S.Sno AS 學號,COUNT(SC.Cno) AS 選課門數 FROM Student S LEFT JOIN SC ON S.Sno = SC.Sno WHERE Dept = '計算機系' GROUP BY S.Sno12

例子解析: 上述例子要求統計每個學生的….,所以在GROUP BY分組時,是按照學生表中的學號來分。而對于聚合函數COUNT,上述要求統計每個學生的選課門數,若寫成COUNT(S.Sno)或COUNT(*),則對沒選課的學生都返回1,因為在外連接結果中,S.Sno不會是NULL,而COUNT(*)函數本身也不考慮NULL,它是直接對元祖個數進行計數。

注意:在對外連接的結果進行分組、統計等操作時,一定要注意分組依據列和統計列的選擇。





1.4 使用TOP限制結果集行數

在使用SELECT語句進行查詢時,有時只需要前幾行數據。

TOP (expression) [PERCENT] [WITH TIES]1
  • expression:指定返回行數的數值表達式。如果指定了PERCENT,expression將隱式轉換成float,否則是bigint

  • PERCENT:指定只返回結果集中前 expression% 行數據。

  • WITH TIES:指定從基本結果集中返回額外的數據行(只有在SELECT子句中包含了ORDER BY子句時,才能使用)。

TOP謂詞寫在SELECT單詞的后面(如果有DISTINCT,則在DISTINCT后面)。

(查詢考試成績最高的3個成績。列出學號、課程號、成績)SELECT TOP 3 Sno,Cno,Grade FROM SC ORDER BY Grade DESC若要包括并列第3名的成績:SELECT TOP 3 Sno,Cno,Grade WITH TIES FROM SC ORDER BY Grade DESC1234





2.數據更改功能

2.1 插入數據

INSERT INTO 表名[(列名)] VALUES (值)1

(1)簡單插入語句

INSERT INTO Student VALUES ('001','陳東','男','1996/6/23','信息管理系')1

(2)多行插入語句

INSERT INTO SC VALUES('001','C001',90),
                     ('001','C002',30),
                     ('001','C005',NULL)123

(3)不按表順序插入語句 
按與表列順序不同的順序插入數據

INSERT INTO Student(Sno,Sname,Sex,Dept) VALUES ('001','陳東','男','1996/6/23','信息管理系')1




2.2 更新數據

UPDATE 表名 SET 列名 = 值1

(1)無條件更新

UPDATE SC SET Grade = Grade+101

(2)有條件更新

(將“C001”號課程的學分改成5分)UPDATE Course SET Grade = 5 WHERE Cno = 'C001'(將計算機系全體學生的成績加5分)UPDATE SC SET Grade = Grade+5 FROM SC JOIN Student S ON S.Sno = SC.Sno WHERE Dept = '計算機系' 12345




2.3 刪除數據

DELETE [TOP (expression) [PERCENT]]    FROM 表名12

(1)無條件刪除

DELETE FROM Student1

(2)有條件刪除

(刪除所有考試成績不合格的學生的選課記錄)DELETE FROM SC WHERE Grade < 60(刪除Student表中2.5%的行數據)DELETE TOP (2.5) PERCENT FROM Student12345






四. 高級查詢

1. CASE函數

CASE函數是一種多分支函數,它可以根據條件列表的值返回多個可能的結果表達式中的一個。

1.1 簡單CASE函數

CASE input_expression    WHEN when_expression THEN result_expression
    [...n]
    [ELSE else_expression]END12345
  • input_expression:所計算的表達式,可以是一個變量名、字段名、函數或子查詢。

  • when_expression :要與input _expression進行比較的簡單表達式。簡單表達式中不可包含比較運算法,只需給出被比較的表達式或值。

  • else_expression : 比較結果均不為TRUE時返回的表達式。

(查詢選了JAVA課程的學生的學號、姓名、所在系、成績,
若所在系為“計算機系”,則顯示“CS”;若所在系為“信息管理系”,則顯示“IM”;若所在系為“通信工程系”,則顯示“COM”)SELECT S.Sno 學號,Sname 姓名,    CASE Dept        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 = 'Java'1234567891011

1.2 搜索CASE函數

簡單 CASE函數只能將input_expression與一個單值進行比較,如果需要跟一個范圍內的值進行比較,就需要搜索CASE函數。

CASE 
    WHEN Boolean_expression THEN result_expression
    [...n]
    [ELSE else_expression]END12345
  • Boolean_expression :比較表達式,可以包含比較運算符,直接將兩者進行比較。

上述例子也可以用搜索CASE函數:SELECT S.Sno 學號,Sname 姓名,    CASE 
        WHEN Dept = '計算機系' THEN 'CS'
        WHEN Dept = '信息管理系' THEN 'IM'
        WHEN Dept = '通信工程系' 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 = 'Java'(查詢C001課程的考試情況,列出學號和成績,然后根據成績劃分等級)SELECT S.Sno 學號,Sname 姓名,    CASE 
        WHEN Grade >= 90 THEN '優'
        WHEN Grade BETWEEN 80 AND 99 THEN '良'
        WHEN Grade BETWEEN 70 AND 79 THEN '中'
        WHEN Grade BETWEEN 60 AND 69 THEN '及格'
    END AS 成績    FROM  SC ON WHERE Cno = 'C001'123456789101112131415161718192021




2. 子查詢

如果一個SELECT語句嵌套在另一個SELECT、INSERT、UPDATE或DELETE語句中,則稱為子查詢或內層查詢;而包含子查詢的語句稱為主查詢。

子查詢通常用于滿足下列需求之一:

  • 把一個查詢分解成一系列的邏輯步驟

  • 提供一個列表作為WHERE子句和IN、EXISTS、ANY、ALL的目標對象

  • 提供由外層查詢中每一條記錄驅動的查詢

子查詢通常有幾種形式:

  • WHERE 列名 [NOT] IN (子查詢)

  • WHERE 列名 比較運算符 (子查詢)

  • WHERE EXISTS(子查詢)

2.1 使用基于集合測試的嵌套子查詢

使用嵌套子查詢進行基于集合的測試時,子查詢返回的是一個值列表,外層查詢通過運算符 IN 或 NOT IN,對子查詢返回的結果集進行比較。

SELECT <查詢列表> FROM ...WHERE <列名> [NOT] IN (
SELECT <列名> FROM)123

包含這種子查詢形式的查詢語句是分步驟實現的,即先執行子查詢,然后在子查詢的結果基礎上執行外層查詢(先內后外)。子查詢返回的結果是一個集合,外層查詢就是在這個集合上使用IN運算符進行比較。

(查詢與劉晨在同一系的學生)SELECT Sno,Sname,Dept FROM Student WHERE Dept IN
    (SELECT Dept From Student Where Sname = '劉晨')

(查詢選修了JAVA課程學生的姓名)SELECT Sname FROM Stduent WHERE Sno IN(    SELECT Sno FROM SC WHERE Cno IN(        SELECT Cno FROM Course WHERE Cname = 'JAVA'))

第二個例子也可以用了連接查詢來做:SELECT Sname From Student S JOIN SC ON S.Sno = SC.Sno JOIN Course C ON C.Cno = SC.Cno WHERE Cname = 'JAVA'1234567891011

上述的例子可以看出子查詢連接查詢可以互通,但在某些情況下是不可以的:

(統計選了JAVA 課程的學生的姓名和所在系)
子查詢:SELECT Sno 學號,COUNT(*) 選課門數,AVG(Grade) 平均成績    FROM SC WHERE Sno IN(      SELECT Sno FROM SC JOIN Course C 
        ON C.Cno = SC.Cno          WHERE Cname = 'JAVA')     GROUP BY Sno12345678

這個查詢不能完全用連接查詢 實現,因為這個查詢的語義是要先找出選了JAVA課程的學生,然后再計算這些學生的選課門數和平均成績。

連接查詢:

SELECT Sno 學號,COUNT(*) 選課門數,AVG(Grade) 平均成績        FROM SC JOIN Course C ON C.Cno = SC.Cno WHERE Cname = 'JAVA'       GROUP BY Sno12

以上查詢是錯誤的,查出來學生的選課門數都是1 。! 實際上這個1指的是JAVA這一門課程,,其平均成績也是JAVA成績。




【注意:】連接查詢和子查詢的區別:★★★★★

  • 之所以這樣,是因為在執行有連接操作的查詢時,系統首先將所有被連接的表連接成一張大表,這張大表中的數據全部滿足連接條件的數據。之后再在這張連接后的大表上執行WHERE子句,然后是GROUP BY子句。

執行完WHERE子句之后,連接的大表中的數據就只剩下JAVA這一門課程的情況了,顯然不符情況。

  • 對于含有嵌套的子查詢的查詢,是先執行子查詢,然后在子查詢的結果基礎上再執行外層查詢。




【注意:】在子查詢中否定和在外查詢中否定的區別 ★★★★★

IN 和 != 的搭配 相較于 NOT IN 和 =的搭配是否相同? 
在子查詢中否定和在外查詢中否定的區別?

(查詢沒選C001課程的學生的姓名和所在系)

1.多表連接:SELECT Sname,Dept FROM Student S JOIN SC ON S.Sno= SC。Sno WHERE Cno != 'C001'2. 嵌套子查詢:1)在子查詢中否定SELECT Sname,Dept FROM Student    WHERE Sno NOT IN(      SELECT Sno FROM SC WHERE Cno = 'C001')2)在外層查詢中否定SELECT Sname,Dept FROM Student    WHERE Sno IN(      SELECT Sno FROM SC WHERE Cno != 'C001')123456789101112131415

這個例子,連接查詢是錯誤的,嵌套子查詢中方法一在子查詢中的否定是錯誤的!嵌套子查詢中方法二在外查詢中的否定是正確的!

【連接查詢】: 
- 上面已經講過,對于連接查詢,所有的條件都是在連接之后的結果表上進行的,而且是逐行進行判斷。一旦發現滿足要求“Cno != ‘C001’”,則此行滿足條件。所以最后的結果既包括沒有選C001課程的學生,也包含選了C001同時選了別的課程的學生。

【含有嵌套的子查詢】: 
對于含有嵌套的子查詢的查詢,是先執行子查詢,然后在子查詢的結果基礎上再執行外層查詢。而且在子查詢中也是逐行判斷的,當發現有滿足條件的數據時,將此行數據作為外行查詢的一個比較條件。

本例要查詢的是某個學生所選的全部課程中均不包含C001課程,如果將否定放在子查詢中,則查出的學生既包括沒有選C001課程的學生,也包含選了C001同時選了別的課程的學生。顯然,這個否定的范圍不夠。

通常情況下,對于這種帶有部分否定條件的查詢都應該用子查詢來實現,而且應該放在外層!




2.2 使用比較測試的嵌套子查詢

SELECT <查詢列表> FROM...
    WHERE <列名> 比較運算符 (
      SELECT <列名> FROM ...)123

使用嵌套子查詢進行比較測試時,要求子查詢只能返回單個值。外層查詢一般通過比較運算符(=、<>、 <= 、>=),將外層查詢中某個列的值與子查詢返回的值進行比較。

(查詢選了C004 課程且成績高于此課程的平均成績的學生的學號和成績)SELECT Sno, Grade FROM SC    WHERE Cno = 'C004' AND Grade >(      SELECT AVG(Grade) FROM SC WHERE Cno = 'C004'1234



2.2 使用SOME 和 ALL 嵌套子查詢

當子查詢返回單值時,可以使用比較運算符進行比較,但返回多值時,就需要通過SOME和ALL修飾,同時必須使用比較操作符!

WHERE <列名> 比較運算符 [SOME | ALL](子查詢)1
(查詢其他學期開設的課程中比第一學期開設課程的學分少的課程名、開課學期、學分)SELECT Cname,Semester,Credit FROM Course    WHERE Credit < SOME(      SELECT Credit FROM Course        WHERE Semester = 1)AND Semester != 1123456

該語句實際上等價于:查詢比第一學期學分最高的課程的學分小的其它學期的課程名、開課學期和學分:

SELECT Cname,Semester,Credit FROM Course    WHERE Credit < (      SELECT MAX(Credit) FROM Course        WHERE Semester = 1)AND Semester != 112345

(查詢至少有一次成績大于或等于90分的學生的學號及選修的全部課程的課程號和考試成績)SELECT Sname,Cno,Grade FROM Student S    JOIN SC ON S.Sno = SC.Sno     WHERE S.Sno = SOME (      SELECT Sno FROM SC 
          WHERE Grade >= 90)123456

該語句實際上是查詢成績大于或等于90的學生的學號及選修的全部課程的課程號和考試成績 
,可用子查詢來做:

SELECT Sname,Cno,Grade FROM Student S    JOIN SC ON S.Sno = SC.Sno     WHERE S.Sno IN (      SELECT Sno FROM SC 
          WHERE Grade >= 90)


標簽:
文章標題: SQL SERVER 基礎篇(一):知識點、SQL語句學習及詳細總結
文章網址:http://www.txwlqq.com/shujuku/SQLserver/3840.html
上一篇:sql server 2008 基礎知識
下一篇:SQL Server 知識點!
來頂一下
返回首頁
返回首頁
相關文章
    無相關信息
推薦資訊
如何通過SEO優化排名賺錢?SEO賺錢方法
如何通過SEO優化排名賺
seo優化教程:網站seo內容優化
seo優化教程:網站seo
SEO細節:企業SEO如何快速為新站做出效果
SEO細節:企業SEO如何
電商技術將如何發展?2018年有這五個大膽預測
電商技術將如何發展?
最新文章
欄目更新
欄目熱門
成人黄色