數據查詢功能:sql
Select <目標列名序列( 須要的列 )> from <數據源( 表格 )> [where<檢索條件表達式>] [Group by <分組依據列>] [having <組提取條件>] [order by <排序依據列>]
學生表(student)函數
課程表(course)學習
成績表(sc)spa
1.查詢指定的列code
select Sno ,Sname,sdept From Student
2.查詢所有列對象
select * from Student
、排序
3.根據已知參數查詢ip
select Sname ,'生日',2018 - Sage from Student
4.指定列的別名內存
列名|表達式 [AS] 列別名 或者 列別名=列名|表達式 select Sname ,'生日' as 常量列 ,2018 - Sage as 年份 from Student
5.去除重複列字符串
select distinct Sno from sc
6.查詢知足條件的元組
關鍵字(WHERE)
select Sname from Student Where Sdept ='計算機系'
select Sname,Sage from Student Where Sage <20
select Sname,Sage from Student Where not Sage >=20
經常使用的where的查詢條件
7.肯定範圍between ....and和not between....and
格式:列名|表達式 [NOT] between 下限值 and 上限值(包括邊界值) select Sname,Sage,sdept from Student where Sage between 20 and 23 (where Sage <20 or Sage>23 )
建立圖書表:
create table book( Number char(8) primary key, BookName char(20) not null, price real not null, data datetime not null ) go
select *from book where date between '2009/6/1' and '2009/6/30'
日期類型的常量要用單引號引發來,並且年,月,日之間一般用分隔符隔開,經常使用的分隔符有「/」和「-」
8.肯定集合
關鍵字IN
select Sname ,Ssexn from Student where Sdept(NOT) IN('信息系','數學系','計算機系')
9.字符串匹配
LIKE關鍵字
LIKE的通用形式: 列名 [NOT] LIKE <匹配串> 通配符: _:匹配任意一個字符; %:匹配0個或多個字符; []:匹配[]當中的任意一個字符 [^]:不匹配[]中的任意一個字符
例如查詢姓「張」的學生詳細信息
select * from Student Where Sname Like '張%' select * from Student Where Sname Like '[張李劉]%' select * from Student Where Sname Like '張%' OR Sname Like '李%'
查詢全部不姓‘王’也不姓‘張’的學生的姓名。
select * from Student Where Sname NOT Like '[王張]%' where Sanme Like '[^王張]%' where Sname NOT LIKE '王%' AND Sname NOT LIKE '張%'
查詢姓「王」且名字是2個字的學生的姓名。
select Sname from Student Where Sname like '王_'
查詢姓「王」且名字是3個字的學生的姓名。
select Sname from Student Where Sname like '王_ _'
若是但願系統在比較時可以去掉尾隨空格的干擾可使用sql去掉尾隨空格的函數:rtrim(列名)
由於系統在存儲「王敏」時固定的char爲10個空間因此還要在其後面添加6個空格也就是6個字符
改變後的格式:
select Sname From Student Where rtrim (Sname) LIKE '王__'
查詢學號的最後一位不是2,3,5的學生的信息
select * from Student where Sno like '%[^235]'
若是要查找的字符串正好含有通配符,就須要使用一個特殊得轉義字符
escape('a')表示位於a字符後面的字符不是轉義字符
`where fieldl like '%30!%%' Escape '!'` 查詢含有30%的字段 `where fieldl like '%!_%' Escape '!'` 包含_的字段
10.涉及NULL的查詢
判斷某個值是否爲null值,不能使用普通的比較運算符(=,!= 等)
判斷列值爲空:
列名 IS NULL
判斷列值爲非空:
列名 IS NOT NULL
查詢全部非空的考試成績學生的學號,課程號,和成績:
select Sno,Cno, From ,Grade from Sc WHERE Grade IS Not NULL
11.多重條件查詢
關鍵字and和or(AND的優先級大於OR)
select Sname FROM Student WHERE Sdept ='計算機系' AND Sage<20
這裏由於AND的優先級大於OR要用括號進行區分
select Sname ,Sdept,Sage from Student where (Sdept ='計算機系' OR Sdept='信息系') AND Sage>=20
也能夠用IN語句避免優先級關係
select Sname ,Sdept,Sage From Student WHERE Sdept IN('計算機系','信息系') AND Sage >=20
12.對查詢的結果進行排序
ORDER BY <列名> [ASC|DESC] [,....n](默認的排序方式爲升序排列)
全體學生年齡按升序排列:
select *from From order by sage ASC
選修c02這門課的學生按降序排列:
select Sno ,Grade from SC where cno='c02' order by grade DESC
查詢結果讓所在系的系名升序排列,同一系的學生按年齡降序排列:(這個地方的使用注意體會!)
select * from Student order by Sdept ASC,Sage DESC
13.使用聚合函數彙總數據
count(*):統計表中元組的個數。 count([distinct]<列名>):統計本列非空列值個數,distinct表示不包括列的重複值。 sum(<列名>):計算列值總和(必須是數值類型) avg(<列名>):計算列值平均值(必須是數值整形) max(<列名>):求列值的最大值 min(<列名>):求列值的最小值
上面的函數中除了count(*)外,其餘函數在計算過程當中均忽略NULL再計算(count計算時若是這一行都爲null也算一行)
統計學生總人數:select count(*) from Student
統計了選修課程的學生人數:select count (distinct Sno)from SC(注意一個學生能夠選擇多門課)
統計'9512101'學生的選課門數和考試總成績:select count(*) as 選課門數,Sum(Grade)as 總成績 from SC
WHERE Sno ='9512101'
注意:聚合函數不能出如今where字句當中。
例如:select Sname FROM Student where Sage = MAX(Sage)
是錯誤的寫法。
14.對查詢結果進行分組的統計
前面所列舉的經過聚合函數的例子都是對全表數據進行統計的,有時咱們但願計算的精度更高一些,好比統計每一個學生的考試平均成績,而不是全體學生的考試平均成績,這時就要用到查詢語句的分組功能。
關鍵字:GROUP BY
分組子句跟在where子句的後邊,通常形式:
GROUP BY <> [,....] [HAVING <組選擇條件>]
注意:分組依據列不能是text,ntext,image,bit類型的列。
使用group by子句
統計每門課程的選課人數,列出課程和選課的人數。
select Cno as 課程號,Count (Sno) as 選課人數 from SC group by Cno
該語句首先對sc表的數據按Cno的值進行分組,全部具備相同Cno值的元組歸爲一組,而後再對每一組的元組使用count進行計算,求得每一組的學生的人數。
2.統計每一個學生的選課門數和平均成績
select Sno 學號,count(*) 選課門數,average (Grade) 平均成績 from sc gropu by Sno
3.統計每一個系的學生人數和平均年齡
select Sno 學號,Count(*) 選課門數 ,avg(Grade) 平均年齡 from Sc group by Sno
總結: 統計哪一列的各類參數就將哪一列進行分組
4.用帶where子句的分組,統計每一個系的女生人數和最大年齡。(按列進行分組而後再按組裏面的值有選擇的進行運算,而不是直接整組運算能夠用where進行修飾)
select Sdept ,count(*) 女生人數 from Student where Ssex ='女' group by Sdept
5.按多列進行分組,統計每一個系的男生人數和女生人數,以及男生的最大年齡和女生的的最大年齡,結果按繫命的升序排列。
select Sdept ,Ssexn ,Count (*) 人數,max(Sage) 最大年齡 from Student Group by Sdept ,Ssexn Order by Sdept
6.使用having子句
例:查詢選修了3門以上學生學號和選課的門數
select Sno ,Count(*) 選課的門數 from sc group BY Sno HAVING COUNT(*)>3
先執行group by對Sno進行分組,而後再用統計函數count對每一組的元組個數進行統計,最後找出大於3的那一組。
例:查詢選課門數大於等於4門的學生的平均成績和選課門數。
select Sno,Avg(Grade) 平均成績,count(*) 選課門數 from sc Group by Sno having count (*)>=4
總結:
建議將全部應該分組以前進行的搜索條件放在where子句而不是having子句中,這樣寫的效率更高一些。
查詢計算機系和信息系的學生人數
第一種
select Sdept ,Count (*) from Student GROUP BY Sdept having Sdept IN('計算機系','信息系')
第二種
select Sdept ,Count(*) from Student where Sdept in('計算機系','信息系') group by Sdept
很顯然第二種的效率更高一些。
可是要注意一點有時候只能用where限定
例:查詢每一個系年齡小於等於20歲的學生的人數。
select Sdept ,count(*) from Student where Sage <=20 group by Sdept
注意該語句不能夠寫成
select Sdept ,count(*) from Student group by Sdept having Sage <=20
這裏是由於having是在分組統計以後再進行這是隻包含分組依據列(系別和人數)因此沒有Sage元素。
15.多表鏈接查詢
1.內鏈接
內鏈接是一種經常使用的鏈接類型,若是兩個表的字段知足鏈接條件,則能夠從這兩個表裏面提取數據並組和成新的記錄。
內鏈接的語法格式:
from 表1 [inner] join 表2 ON <鏈接條件>
鏈接條件的通常格式:
[<表名 1.>] [<列名 1>]<比較運算符> [<表名 2.>][<列名 2>]
當比較運算符爲等號(=)是時,稱爲等值鏈接,其餘的稱爲非等值鏈接。
例:
查詢每一個學生及其選課的詳細信息。
select * from Student Inner JOIN sc on Student.Sno=sc.Sno
在寫多鏈接表時有必要將這些重複的列給去掉,方法是在select 子句中直接列出所須要的列名,而不是'*',另外因爲多表鏈接後,在鏈接生成的表中可能存在列名相同的列,所以爲了明確到底須要哪一個列,能夠在列名的前面添加表名前綴限制,其格式:表名.列名
去掉上圖中的重複列
select Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade from Student [Inner] JOIN sc on Student.Sno=sc.Sno
例:查詢計算機系的學生的修課狀況,要求列出學生的名字,所選擇課程號和成績
select Sname ,Cno ,Grade FROM Student JOIN sc ON Sudent .Sno =sc.Sno where Sdept ='計算機系'
能夠爲表提供別名,其格式以下:
from <源表名> [as] <表別名>
爲表指定別名能夠簡化表的書寫,並且在有些鏈接查詢中要求必須指定別名。
select Sname ,Cno,Grade From Student S join sc
這裏要注意的是當你爲表指定了別名在查詢語句的其餘地方,全部用到表民的地方都要使用別名,而不能在使用原表名。
例:查詢信息系選修了計算機文化學課程的學生的信息,要求列出學生的姓名,課程名和成績。
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='計算機文化學'
查詢全部選修了VB課程的學生狀況,列出學生的姓名和所在的系。
select Sname,Sdept From Student S JOIN sc ON S.Sno=sc.Sno JOIN course c ON c.Cno=sc.Cno where Sdept ='VB'
注意:由於原本所須要的數據與sc表無關可是Student和Course沒有能夠進行鏈接的元素,因此這是須要引入sc表進行鏈接。
2.自鏈接
自鏈接是一種特殊的內鏈接,相互鏈接的表在物理表上爲同一張表,但在邏輯上將其當作兩張表。from 表1 T1
---在內存中生成表名爲T1的表join 表1 T2
---在內存中生成表名爲T2的表
所以在自鏈接時必定要爲表取別名。
查詢與劉晨在一個系學習的全部學生的姓名和所在系
select S2.Sname ,S2.Sdept from Student S1 join Student S2 on S1.Sdept=S2.Sdept where S1.Sname='劉晨' AND S2.Sname!='劉晨'
----->
分析:
先在s1中找出劉晨這一項數據而後在s2中找出除劉晨外的計算機系全部學生數據最後S1,S2查詢結果經過計算機系進行鏈接
3.外鏈接
有時候咱們也但願看到那些不知足元組條件的元組信息,好比查看所有學生的選課的狀況既想看到那些課程被選了,哪些課程沒有被選擇。由於內鏈接實現首先要有知足鏈接條件,sc.Cno=course.Cno,若是在sc表中沒有人選擇課程可是在course中卻有,因爲不知足上述條件因此查找不出來。
外鏈接只限制一張表中的數據必須知足鏈接條件,而另外一張表中的數據能夠不知足鏈接條件。
From 表1 left | right [outer] join 表2 ON <鏈接條件>
若是是左外鏈接那麼就是限制表2 中的數據必須知足鏈接條件,而不用管表1中的數據是否知足鏈接條件,均輸出表一中的內容。右鏈接亦同。
例:查詢學生的選課狀況,包括選擇了課程的學生和沒有選擇課程的學生,列出學號,姓名,課程號和成績。
左鏈接: select Student.Sno,Sname,Cno,Grade from Student left outer join sc on Student.Sno =sc.Sno 右鏈接: select Student.Sno,Sname ,Cno,Grade From sc right outer join Student ON Student.Sno=SC.Sno
例:查詢哪些課程沒有人選,列出其課程名。
select Cname FROM Course C left join sc on c.cno=sc.cno where sc.cno is null.
外鏈接操做中可使用where 子句 ,group by子句等
查詢計算機系沒有選課的學生,列出學生的姓名和性別。
select Sname,Sdept,Cno,grade from Student S left join sc on S.sno=sc.Sno where Sdept ='計算機系' and Sc.Sno is null.
假設咱們讓鏈接的兩個表所有打印:------>
------->
分析:首先進行外鏈接以student的sno進行鏈接從student裏面拿一個學號與sc裏面的學號進行比較相等則鏈接當student找不到時則鏈接空值行 鏈接後的表再進行where篩選。注意此時仍是要當成兩個表去看待好比選擇一個計算機系且沒有選課的(Sno爲null)的行就要寫成: where Sdept ='計算機系'(sdept惟一隻屬於student的不用標識) and Sc.Sno(這個須要標識二者都有) is null.
例:統計計算機系每一個學生的選課門數,包括沒有選課的學生,結果按選課門數遞減排列。
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 order by count (sc.sno) desc
首先經過sno進行鏈接
而後經過計算機系進行過濾
最後經過學號進行分組(須要指定由於學號不惟一)統計
並打印指定的參數列
16.使用TOP限制結果集
在使用select語句時咱們但願只顯示這些結果集中的前幾行結果,就可使用top語句。
格式:TOP n [percent] [with ties]
其中:
TOP謂詞寫在select單詞的後邊(若是有distinct的話,則在distinct 單詞以後),查詢列表的前邊。