SQLServer的管理
-
需要安裝SQLServer2005或者SQLServer2008,若要使用SQLServer管理工具進行開發還要安裝SQL Server Management Studio,還可以使用VisualStudio進行管理。
-
使用免費的SQLServerExpress版本,Express版本的服務器名稱.\SQLEXPRESS,對於開發人員來講和其他版本沒有區別。
-
SQLServer的兩種驗證方式:用戶名驗證和Windows驗證,開發時用Windows驗證就行了。
-
開發人員關注點在開發上,而不是配置、備份等之上,那是DBA(數據庫管理員)做的事情。
常用字段類型:bit(可選值0,1)、datetime、int、varchar、nvarchar(可能含有中文的用nvarchar)
Varchar、nvarchar和char(n)的區別:char(n)不足長度n的部分用空格填充。
-
SQL語句是和DBMS“交談”專用的語句,不同DBMS都認SQL語法。
-
SQL語句中字符串用單引號。
-
SQL語句是大小寫不敏感的,不敏感指的是SQL關鍵字,字符串值還是大小寫敏感的。
-
SQL主要分DDL(數據定義語言)和DML(數據操作語言)兩類。Create Table、Drop Table、Alter Table等屬於DDL,Select,Insert,Update,Delete等屬於DML。
-
SQLServer中兩種常用的主鍵數據類型:int(或bigint)+標識列(又稱自動增長字段);uniqueidentifier(又稱Guid,UUID)
-
用標識列實現字段自增可以避免併發等問題,不要開發人員控制自增。用標識列的字段在Insert的時候不要指定主鍵的值。
-
Guid算法是一種產生唯一標識的高效算法,它使用網卡MAC,地址,納秒級世界,芯片ID碼等算出來。保證不會重複。SQLServer中生成GUID的函數newid(),.net中生成Guid的方法:Guid.NewGuid(),返回是Guid類型。
-
Int自增字段的優點:佔用空間小,無需開發人員干預,易讀;缺點:效率低:數據導入導出的時候很痛苦(兩個數據庫合併的時候,id的重複使得合併過程很痛苦)。
-
Guid的優點:效率高,數據導入導出方便;缺點佔用空間大,不易讀。
創建表:
create table T_Person(Id int identity(1,2) not null primary key, Name nvarchar(50),Age int null default 20)
其中primary key把Id設置爲主鍵。
identity(1,2)把主鍵Id設置爲自動增長起始值爲1,步長爲2。
刪除表:
drop table T_Person
插入數據:
insert into T_Person(Name,Age) values(’Jim’,20)
其中主鍵Id已設置爲自動增長,所以不需要賦值。
-
Insert語句可以省略表名後的列名,但是不推薦。
-
如果插入的行中有些字段的值不確定,那麼insert的時候不指定那些列即可。
更新一列數據:update T_Person set Age=45
更新多列數據:update T_Person set Age=30,Name=’tom’
更新一部分數據:update T_Person set Age=42 where Name=’tom’
用where語句表示只更新Name是’tom’的行,注意SQL中等於判斷用單個=,而不是==。
Where中還可以使用複雜的邏輯判斷
update T_Person set Age=40 where Name=’tom’ or Age>25
其中or想到於C#中的||(或者)。
Where中可以使用的其他邏輯運算符:or,and,not,<,>,>=,<=,!=(或<>)等。
數據刪除:
Delete from T_Person
Delete只是刪除數據,表還在,和drop Table不同。
Delete 也可以帶where子句來刪除一部分數據:
Delete from T_Person where Age>20
數據檢索
簡單的檢索:Select * from T_Person
只檢索需要的列:
select Name from T_Person
select Name,Age from T_Person
給列取別名:
Select Name as 姓名,Age as 年齡from T_Person
使用where檢索符合條件的數據:
Select Name from T_Person where Age>45
還可以檢索不與表關聯的數據:
Select 1+1;select newid();select getdate();select @@version
Select count(*)from T_Person
Select max(Age) from T_Person
Select min(Age) fromT_Person
Select avg(Age) from T_Person
Select sum(Age) from T_Person
數據排序:order by
Order by子句位於select語句的末尾,它允許指定按照一個列或者多個列進行排序,還可以指定排序方式是升序(從小到大排列,ASC),還是降序(從大到小排序,DESC)。
按照年齡升序排序:
Select * from T_Person order by Age ASC
按照年齡從大到小排序,如果年齡相同則按照工資從大到小排序:
Select * from T_Person order by Age DESC, Salary DESC
Order by子句要放到where子句之後:
Select * from T_Person
where Age>23
Order by Age DESC, Salary DESC;
通配符過濾
-
通配符過濾使用Like。
-
“_”匹配單個字符。以任意字符開頭,剩餘部分爲“erry”:
Select * from T_Person where Name like ‘_erry’
-
“%”匹配任意字符(零個或多個)。檢索姓名中包含字母”n”的員工信息:
Select * from T_Person where Name like ‘%n%’
空值處理:
-
數據庫中,一個列如果沒有指定值,那麼值就爲null,數據庫中的null表示“不知道”,而不是表示沒有。因此select null+1結果是
null,因爲“不知道”加1的結果還是“不知道”。
-
SQL中使用is null ,is not null來進行空值判斷:
Select * from T_Person where Name is null;
Select * from T_Person where Name is not null;
多值匹配:
Select * from T_Person where Age in(23,24,26)
範圍值:
Select * from T_Person where Age>=23 and Age<=27;
Select * from T_Person where Age between 23 and 27;
數據分組:
按照年齡進行分組統計各個年齡段的人數:
Select Age,Count(*) from T_Person group by Age
Group by 子句必須放到where語句之後。
沒有出現group by子句中的列是不能放到select語句後的列名列表中的(聚會函數除外)
錯誤:select Name,Age from T_Person group by Age
正確:select Age from T_Person group by Age
Having語句
-
在where中不能使用聚合函數,必須使用Having,Having要位於Group by之後,
select Age,count(*) as人數 from T_Person
Group by Age
Having count(*)>1;
-
Having 不能取代where。作用不一樣,Having是對組進行過濾。
限制結果集行數:
Select top 5 * from T_Person order by Age DESC。
(*)檢索按照年齡高低排序檢索從第六名開始一共三個人的信息:
Select top 3 * from T_Person
Where Id not in(select top 5 Id from T_Person order by Age DESC)
Order by Age DESC
SQLServer2005後增加了Row_Number函數簡化實現,在本文最後會提到。
去掉重複數據:
Select distinct Name from T_Person
-
Distinct 是對整個結果集進行數據重複處理的,而不是針對每一個列,
Select distinct Name,Age from T_Person(結果中就會出現同名的但年齡不會相同,或者年齡相同但名字絕對不會相同)
聯合結果集:union
-
Union合併兩個查詢結果集,並且將其中完全重複的數據行合併爲一條。
-
Union 因爲要進行重複值掃描,所以效率低。
-
因此如果不是確定要合併重複行,那麼就用Union all
數字函數(*)
-
ABS():求絕對值
-
Ceiling():舍入到最大整數。3.33將被舍入爲4。Ceiling-->天花板
-
Floor():舍入到最小整數。3.33將舍入爲3。Floorà地板
-
ROUND():四捨五入。舍入到“離我半徑最近的數”。Round—>“半徑”。Round(3.144,2)=3.14
字符串函數(*)
-
Len():計算字符串長度
-
Lower(),upper():轉小寫,大寫。
-
Ltrim():字符串左側的空格去掉
-
Rtrim():字符串右側的空格去掉
-
Ltrim(rtrim(‘ bb ’))結果就是’bb’
-
Substring(string,start_position,length)
參數string爲父字符串,start_position爲字符串在父字符串中的起始位置,length爲子字符串的長度。
Select substring(‘abcdef111’,2,3)結果爲’bcd’
日期函數:
-
Getdate():取得當前日期時間
-
Dateadd(datepart,number,date),計算增加以後的日期。參數date爲計算的日期;參數number爲增量;參數datepart爲計量單位。
Dateadd(day,3,date)爲計算日期date的3天后的日期。
Dateadd(month,-8,date)爲計算日期date的8個月前的日期。
-
Datediff(datepart,startdate,enddate):計算兩個日期之間的差額。
-
Datepart(datepart,date):返回一個日期的特定部分
-
統計員工的入職年份個數:
Select datepart(year,InDate),count(*)
From T_Employee
Group by DatePart(year,InDate)
類型轉換函數:
-
Cast(expression as date_type)
-
Convert(date_type,expression)
-
Select Age,right(Age,1)as 最後一位
空值處理函數
-
Isnull(expression,value):如果expression不爲空則返回expression,否則返回value。
Select isnull(Name,’匿名’)as姓名from T_Person
Case函數用法
單值判斷,相當於switch case
Case expression
When value1 then returnvalue1
When value2 then returnvalue2
When value3 then returnvalue3
Else defaultreturnvalue
End
例子:
Select Name
(case Level
when 1 then ‘VIP客戶’
when 2 then ‘高級客戶’
when 3 then ‘普通客戶’
else ‘客戶類型錯誤’
)as LevelName
From T_Customer
索引
-
全表掃描:對數據進行檢索(select)效率最差的是全表掃描,就是一條條的找
-
如果沒有目錄,查漢語字典就要一頁頁的翻,而有了目錄只要查詢目錄即可。爲了提高檢索的速度,可以爲經常進行檢索的列添加索引,相當於創建目錄。
-
創建索引的方法,在表設計器中點擊右鍵,選擇“索引/鍵”à添加à在列中選擇索引包含的列。
-
使用索引能提高查詢的效率,但是索引也是非常佔據空間的。而且添加,更新,刪除數據的時候也需要同步更新索引,因此會降低insert,update,delete的速度。所以只在經常索引的字段上創建索引。
-
(*)即使創建了索引,仍然有可能全表掃描,比如like,函數,類型轉換等。
表連接Join
-
有客戶表(T_Customers)和訂單表(T_Orders)兩個表,客戶表字段爲:Id,Name,Age.訂單表地段爲:Id,BillNo,CustomerId.訂單表通過CustomerId關聯客戶表。
Select o.BIllNo,c.Name,c.Age
From T_Order as o Join T_Customers as c on o.CustomerId=c.Id
子查詢:
-
將一個查詢語句作爲一個結果集供其他SQL語句使用,就像使用普通的表一樣。所有可以使用表的地方几乎都可以使用子查詢來代替。
最簡單的子查詢:select * from(select * from T_Person where age>30)
-
單值作爲子查詢:select 1 as column1, 2 as column2,
(select min(Age) from T_Person) as column 3,
(select max(Age) from T_Book) as column 4
-
只有返回且僅返回一行,一列數據的子查詢才能當成單值子查詢。
下面是錯誤的:
Select 1 as f1, (select Age from T_Person)
-
如果子查詢是多行單列的子查詢,這樣的子查詢的結果集其實是一個集合。
Select * from T_Reader
Where YearOfJoin in
(select YearPublished from T_Book)
-
限制結果集。返回第三行和第五行的數據:
Select * from
(
Select row_number() over(order by Salary DESC)as rownum, Number,Name,Salary,Age from T_Employee
)as a
Where a.rownum in(3,5)