SQLServer 學習筆記2


1.union、union all、except、intersect之間的區別

(1)union:取兩個表的並集,如果有重復數據,則只留下一個

(2)union all:在並集的基礎上,保留重復的數據

(3)except: 例如select * from A except select * from B,取差集,也就是去掉A和B之間的重復數據,只保留A表獨有的部分

(4)intersect 只保留兩張表之間相同的數據,也就是取交集

 2.自連接

select * from Customers t1,Customers t2 where t1.City <> t2.City;

3.全連接

全連接類似於union,也就是兩個表的並集,查詢后的總條數:A表條數+B表條數-兩者重復條數

4.左連接、右連接

注意一對多、多對一的關系,例如A表有ID為1的一條數據,而B表有3條ID為1的數據,兩表左、右連接,結果為

ID NAME ID NAME
1 A 1 a
1 A 1 b
1 A 1 c

出現這一結果的原因為:1條父數據對應着3條子數據,父數據的信息會自動填充在每條子數據對應的父數據字段。

PS:需要注意的是,連接查詢on之后的條件可以不是A表字段=B表字段,可以是其他條件。

另外SqlServer表別名可用不用AS 直接在后面填寫即可,例如

select A.*,B.C#,B.score from (select * from SC where C# = '01')A --查詢結果做A表
inner join (select * from SC where C# = '02')B--查詢結果做B表
on A.S# = B.S# --兩表連接查詢
where A.score>B.score; 

5.null的問題

例如:select * from Person where pname <> '張三';,如果pname這個字段內有null,則null對應的這行數據會被自動忽略,也就是說邏輯判斷的值是不包含null的。

另外,在update 數據時,如果要填入null,直接填寫字段=null即可,但是在判斷時,要使用 where 字段 is null | is not null。

6.更新、刪除數據時需要注意:

先使用select查詢到要操作的信息,然后再用update、delete進行具體操作,防止誤操作。

7.隱式轉換問題

例如一個字段是int類型,在插入數據時插入'1',數據可以被正確存入,不報錯,這是SQL自動將字符串類型轉換為了整數類型,但是如果輸入的是'a1',則會產生報錯,因為'a1'是無法被轉換為int類型的!

 8.查找每門課最高分問題

先得到相同學科的最高分數,再查詢Scores表,找到最高分數的記錄:

select * from Scores a where a.sco_degree = 
(select max(b.sco_degree) from Scores b where a.sco_cour_id = b.sco_cour_id);

找到每門課的最高分數

select max(sco_degree) from Scores where sco_cour_id = a.sco_cour_id --先篩選出每門學科 即sco_cour_id = a.sco_cour_id,然后求最大值,得出的就是每門課的最高分

然后用本表去篩選這些最高分對應的信息:

select * from Scores a where sco_degree = 

 第二種方式:

(1)先按照課程id把成績表分組,然后求出最高分

select max(sco_degree) score,sco_cour_id from Scores group by sco_cour_id;

(2)然后把上面的結果集做a表,然后成績表做b表,查詢兩者成績、課程編號一樣的數據

select b.* from (select max(sco_degree)score,sco_cour_id from Scores group by sco_cour_id)a,Scores b where a.score = b.sco_degree and a.sco_cour_id = b.sco_cour_id;

9.數據類型

date與datetime的區別:

date時間格式為:yyyy-mm-dd

datetime時間格式為: yyyy-mm-dd hh:mi:ss.ms,精確到毫秒時間,時間格式與getdate()函數格式一樣,因此可以用來計算毫秒時間差,用於性能統計

declare @d datetime
set @d = getdate()
數據操作語句,例如查詢語句等
select ['語句執行耗時'] = datediff(ms,@d,getdate());

 10.獲取當月天數與當月最后一天、第一天

--當月第一天
--當前日期+(-當期日期天數+1) 
--例如 現在時間7月19號 19+(-19+1) = 1
select dateadd(d,-day(getdate())+1,getdate());
--當月最后一天
--下月的這一天減去現在日數 
--例如現在時間7月19 下月 這一天8月19 8/19-19 = 8/0即 7/31
--即使這個月有31號而下月只有30天也沒事,只要產生月份/0日這個結果就可以
select dateadd(d,-day(getdate()),dateadd(m,1,getdate()));
--本月有多少天
select day(dateadd(d,-day(getdate()),dateadd(m,1,getdate())));

 11,in 與 group by

學生表:

 成績表:

現在要查詢和‘1’號學生所學科目完全相同的學生信息

首先要篩選學號,所學科目 in ‘1’號學生所學科目

select S# from SC where C# in (select C# from SC where S# = '01');

查詢出的結果:

select C# from SC where S# = '01'; --查詢出的結果是‘01’,‘02’,‘03’

只要在課程編號在'01','02','03'都被查詢出來,拿08號學生來說,學習了02,03,04三門課,所以只匹配中了兩門,S#查詢出兩個08

然后我們依據S#進行編組查詢:

select S# from SC where C# in (select C# from SC where S# = '01') group by S#;

數據根據S#編組,重復出現的數據被合並,此時我們只需要知道每個S#對應的課程編號數量等於01學生所學的課程數量:

select S# from SC where C# in (select C# from SC where S# = '01') group by S# 
having count(c#)=(select count(c#) from sc where S# = '01');

接下來只需查詢Student表中對應這幾個S#的學生信息即可:

select * from Student where S# in
(select S# from SC where C# in (select C# from SC where S# = '01' )group by S# 
having count(c#)=(select count(c#) from sc where S# = '01'));

 12.數據類型隱式轉換

select count(*)*1.00 from SC group by sid;

count()得到是一個整數,*1.00后隱式轉為浮點數

 13.delete update 高級應用

利用join 會實現條件刪除與更新數據

例:

根據課程表內語文課程考試成績小於60分的學生學號去匹配學生表,匹配中的學生表記錄刪除

delete A from Student A left join Score B on A.sid = B.sid where course = '語文' and degree <60;

 類似的,update也可以這樣使用

 update A set age = 100 from Student A left join Score B on  .... where ....;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM