SQL 學習總結筆記

1、主鍵:業務主鍵(身份證號,手機號)--有業務意義的字段,很難保證不重複或發生變化;邏輯主鍵--沒有實際意義專門給計算機看的字段 
2、 分組:group by 子句在where之後,篩選後分組(分組後再篩選如有被篩選掉的分組也就沒有意義)
--查詢的字段只能是分組的字段或是聚合函數。按性別分組,一組有2個人不可能得到這一組的姓名
select sex,count(*) from temp group by sex;
    SEX   COUNT(*)
1 男                   2
2 女                   1  
3、聚合函數(Max,Count)不能出現在where子句中,但可以用Having(having後的條件只能是聚合函數或是group by 子句中的字段)。having主要對分組後數據進行過濾
select sex,count(*) from temp group by sex having count(*)>1 
4、null
null在數據中表示“不知道”,"不確定的值“ null+1==null(不確定的值加上1還是不確定的值) 但在C#中null表示空(string str=null str+"abc"==abc)  
空或非空時用is null 或is not null(因爲=null 有一個判定的存在,什麼值也不可能等於不確定的值,而is null代表”是 null" )
select * from exam where salary is null--is not null   
5、代碼不是越少越好是越容易讀越好。
6、通配符(模糊查詢):
“_"一個英文下劃線 匹配一個的字符 例如:p_ 可以匹配pa; 
”%“一個百分號 匹配0或任意個字符 例如:%p 可以匹配p、ap、aap; p%可以匹配pa、paa
”%%"兩個百分號 包含某個字符的任意字符 例如:%p% 可以匹配包含p的任意字符
7、between...and... 指定一個範圍("between 21 and 24" 包括21和24)
select * from exam where age between 21 and 24 等價於 select * from exam where age>=21 and age<=24(開發時更習慣用) 
8、nvarchar和varchar的區別
varchar 存儲本地的字符,nvarchar存儲國家字符集
9、char和varchar(var==variable可變的)相比 char會用空格填充剩餘字符的位置
10、rownum:對結果集加的一個僞列,先查到結果在加上rownum,總是從1開始不可能查到到1而不包含1的數據
先查詢生成rownum,後排序。<=時可以取,>=時取完還要排序會亂所以查不出數據只能用子查詢
無法直接使用>,>=,=,between...and
11、限制結果集的行數(查詢第4--9行數據) -----分頁查詢
SQL Server:
select top 3 * from exam where id not in(select top 2 id  from exam)
Oracle:
(1)select * from (select a.*,rownum r from exam a where rownum <=5) where r>=3
(2)用分析函數解決
select * from (select a.*,row_number()over(order by name) as num from exam a)where num between 3 and 5
(1)(2)比較:(1)中涉及到排序的話需要先排序在生成序號然後進行篩選,至少3次嵌套沒有(2)的效率快  
12、union 參與union的兩個結果集個數和類型必須相同,可以是不同的數據字段。如果某一個結果集缺少字段時可以用相同的數據類型補全
union會去掉合併後的重複項,union all不會。union會掃描重複項效率沒有union all高,如果不要求去掉重複項或是確定沒有重複項用union all
select age,name,salary from exam
union
select age,name,0 as salary from employee
13、SQL Server 日期函數
getdate()--獲取當前時間
dateadd(day,3,getdate())--當前日期加3天
datediff(year,indate,getdate())--日期間隔
datepart(year,getdate)---取回日期的指定部分
統計某一年份入職員工的個數
select datepart(year,indate) as 年份,count(*) as 個數 from exam
group by datepart(year,indate)
Oracle 日期函數
sysdate---獲取服務器當前時間
to_date('2012-09-12','yyyy-mm-dd')
to_char(sysdate,'yyyy-mm-dd')
add_months(sysdate,1)--當前日期加一月
sysdate+21---當前日期加21天
add_months(sysdate,12);sysdate+interval '1' year---加一年(year)
interval 也可以加月(month)/日(day)
14、‘123’+1 結果雖爲124 但有時會有問題 最好to_number('123')+1
15、把查出結果中爲null類型數據替換成指定類型 Oracle:nvl(age,18) SQL Server:isnull(age,18)
16、case...when...then...end
1)類似switch case的非離散值
select name,
(
       case leveId
         when 1 then '普通用戶'
         when 2 then '高級用戶'
         when 3 then 'vip用戶'
         else '未知用戶類型'
       end
) as 用戶類型
from leve
2)判斷某一個範圍的離散值
select name,
(
       case --case判定範圍時不加任何東西
         when salary<2000 then '低收入水平'
         when salary>=2000 and salary<=5000 then '中等收入水平'
         else '高收入水平'
       end
) as 收入水平
from exam
17、case的綜合應用
    SCOREDATE NAME SCORE
1 2012/9/2 湖人
2 2012/6/2 小牛
3 2012/4/5 湖人
4 2012/7/10 奇才
5 2012/9/5 小牛
6 2012/9/11 拜仁
7 2012/5/22 拜仁
轉換成:
    NAME
1 小牛 1 1
2 奇才 0 1
3 湖人 1 1
4 拜仁 1 1
select name,
sum(
       case score
         when '勝' then 1
         else 0
       end
) as 勝,
sum(
       case score
         when '負' then 1
           else 0
       end 
) as 負
from scores group by name
思路:
(1)構造勝、負兩列,要求用勝負的場數表示所有勝負分別爲1否則爲0
(2)統計每個隊的勝負情況,依據隊分組
(3)求每對具體的勝負總數



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章