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 ....;
