自從用了EF後不多寫sql和存儲過程了,今天須要寫個比較複雜的報告,翻出了以前的筆記作參考,感受這個筆記仍是頗有用的,所以發出來和園友分享。html
一、case...end (具體的值)
case後面有值,至關於c#中的switch case
注意:case後必須有條件,而且when後面必須是值不能爲條件。
sql
-----------------case--end---語法結構--------------------- select name , --注意逗號 case level --case後跟條件 when 1 then '骨灰' when 2 then '大蝦' when 3 then'菜鳥' end as'頭銜' from [user]
二、case...end (範圍)
case 後面無值,至關於c#中的if...else if...else....
注意:case後不根條件數據庫
------------------case---end-------------------------------- select studentId, case when english between 80 and 90 then '優' when english between 60 and 79 then '良' else '差' end from Score ------------------case---end-------------------------------- select studentId, case when english >=80 then '優' when english >=60 then '良' else '差' end from Score ----------------------------------------------------- select *, case when english>=60 and math >=60 then '及格' else '不及格' end from Score
三、if...elesexpress
IF(條件表達式) BEGIN --至關於C#裏的{ 語句1 …… END --至關於C#裏的} ELSE BEGIN 語句1 …… END --計算平均分數並輸出,若是平均分數超過度輸出成績最高的三個學生的成績,不然輸出後三名的學生 declare @avg int --定義變量 select @avg= AVG(english) from Score --爲變量賦值 select '平均成績'+CONVERT(varchar,@avg) --打印變量的值 if @avg<60 begin select '前三名' select top 3 * from Score order by english desc end else begin select '後三名' select top 3 * from Score order by english end
四、while循環c#
WHILE(條件表達式) BEGIN --至關於C#裏的{ 語句 …… BREAK END --至關於C#裏的} --若是不及格的人超過半數(考試題出難了),則給每一個人增長分 select * from Score declare @conut int,@failcount int,@i int=0 --定義變量 select @conut =COUNT(*) from Score --統計總人數 select @failcount =COUNT(*) from Score where english<100 --統計未及格的人數 while (@failcount>@conut/2) begin update Score set english=english+1 select @failcount=COUNT(*) from Score where english<100 set @i=@i+1 end select @i update Score set english=100 where english >100
五、索引
使用索引能提升查詢效率,可是索引也是佔據空間的,並且添加、更新、刪除數據的時候也須要同步更新索引,所以會下降Insert、Update、Delete的速度。只在常常檢索的字段上(Where)建立索引。
1)彙集索引:索引目錄中的和目錄中對應的數據都是有順序的。
2)非彙集索引:索引目錄有順序但存儲的數據是沒有順序的。數組
--建立非彙集索引 CREATE NONCLUSTERED INDEX [IX_Student_sNo] ON student ( [sNo] ASC )
六、子查詢
將一個查詢語句作爲一個結果集供其餘SQL語句使用,就像使用普通的表同樣,被看成結果集的查詢語句被稱爲子查詢。全部可使用表的地方几乎均可以使用子查詢來代替。安全
select * from (select * from student where sAge<30) as t --被查詢的子表必須有別名 where t.sSex ='男' --對子表中的列篩選
轉換爲兩位小數:CONVERT(numeric(10,2), AVG(english))
只有返回且僅返回一行、一列數據的子查詢才能當成單值子查詢。網絡
select '平均成績', (select AVG(english) from Score) --能夠成功執行 select '姓名', (select sName from student) --錯誤,由於‘姓名’只有一行,而子表中姓名有多行 select * from student where sClassId in(select cid from Class where cName IN('高一一班','高二一班')) --子查詢有多值時使用in
七、分頁ide
--分頁1 select top 3 * from student where [sId] not in (select top (3*(4-1)) [sid] from student)--4表示頁數 select *, row_number() over(order by [sage] desc ) from student-- row_number() over (order by..)獲取行號 --分頁2 select * from (select *, row_number() over(order by [sid] desc ) as num from student)as t where num between (Y-1)*T+1 and Y*T order by [sid] desc
--分頁3
select * from (select ROW_NUMBER() over( order by [UnitPrice] asc) as num,* from [Books] where [publisherid]=1 )as t where t.num between 1 and 20 --要查詢的開始條數和結束條數
八、鏈接模塊化
select sName,sAge, case when english <60 then '不及格' when english IS null then '缺考' else CONVERT(nvarchar, english) end as'英語成績' from student as s left join Score as c on s.sid =c.sid 內鏈接 inner join...on... 查詢知足on後面條件的數據 外鏈接 左鏈接 left join...on... 先查出左表中的全部數據 再使用on後面的條件對數據過濾 右鏈接 right join...on... 先查出右表中的全部數據 再使用on後面的條件對數據過濾 全鏈接 full join ...on... (*)交叉鏈接 cross join 沒有on 第一個表的每一行和後面表的每一行進行鏈接 沒有條件。是其它鏈接的基礎
9.視圖
優勢:
建立視圖
create view v_Demo as select ......
十、局部變量
---------------------------------局部變量-------------------------- --聲明變量:使用declare關鍵字,而且變量名已@開頭,@直接鏈接變量名,中間沒有空格。必須指明變量的類型,同時還能夠聲明多個不一樣類型的變量。 declare @name nvarchar(30) ,@age int --變量賦值: --一、使用set 給變量賦值,只能給一個變量賦值 set @age=18 set @name ='Tianjia' select @age,@name --輸出變量的值 --二、使用select 能夠同時爲多個變量賦值 select @age=19,@name='Laoniu' --三、在查詢語句中爲變量賦值 declare @sum int =18 --爲變量賦初值 select @sum= SUM(english) from Score --查詢語句中賦值 select @sum --輸出變量值 --四、變量做爲條件使用 declare @sname nvarchar(10)='張三' declare @sage int select @sage=sage from student where sName=@sname select @sage --五、使用print輸出變量值,一次只能輸出一個變量的值,輸出爲文本形式 print @sage
十一、全局變量
--------------------------全局變量(系統變量)---------------------------------- select * from student0 select @@error --最後一個T-SQL錯誤的錯誤號 select @@max_connections--獲取建立的同時鏈接的最大數目 select @@identity --返回最近一次插入的編號
十二、事務
事務:同生共死
指訪問並可能更新數據庫中各類數據項的一個程序執行單元(unit)--也就是由多個sql語句組成,必須做爲一個總體執行
這些sql語句做爲一個總體一塊兒向系統提交,要麼都執行、要麼都不執行
語法步驟:
判斷某條語句執行是否出錯:
全局變量@@ERROR;
@@ERROR只能判斷當前一條T-SQL語句執行是否有錯,爲了判斷事務中全部T-SQL語句是否有錯,咱們須要對錯誤進行累計;
---------------------------模擬轉帳---------------------------- declare @sumError int=0 --聲明變量 begin tran update bank set balance=balance-1000 where cId='0001' set @sumError=@sumError+@@error update bank set balance=balance+1000 where cId='0002' set @sumError=@sumError+@@error if (@sumError=0) commit tran --提交成功,提交事務 else rollback tran --提交失敗,回滾事務
1三、存儲過程
存儲過程---就像數據庫中運行方法(函數)
和C#裏的方法同樣,由存儲過程名/存儲過程參數組成/能夠有返回結果。
前面學的if else/while/變量/insert/select 等,均可以在存儲過程當中使用
優勢:
系統存儲過程
由系統定義,存放在master數據庫中
名稱以「sp_」開頭或」xp_」開頭
建立存儲過程:
定義存儲過程的語法 CREATE PROC[EDURE] 存儲過程名 @參數1 數據類型 = 默認值 OUTPUT, @參數n 數據類型 = 默認值 OUTPUT AS SQL語句 參數說明: 參數可選 參數分爲輸入參數、輸出參數 輸入參數容許有默認值 EXEC 過程名 [參數] ----------------------例-------------------------- if exists (select * from sys.objects where name='usp_GroupMainlist1') drop proc usp_GroupMainlist1 go create proc usp_GroupMainlist1 @pageIndex int, --頁數 @pageSize int, --條數 @pageCount int output--輸出共多少頁 as declare @count int --共多少條數據 select @count =count(*) from [mainlist] --獲取此表的總條數 set @pageCount=ceiling(@count*1.0/@pageSize) select * from (select *,row_number() over(order by [date of booking] desc) as 'num' from [mainlist]) as t where num between(@pageSize*(@pageIndex-1)+1) and @pageSize*@pageIndex order by [date of booking] desc ------------------------------------------------------------------------------------------- --調用 declare @page int exec usp_GroupMainlist1 1,100,@page output select @page
1四、經常使用函數
1)ISNULL(expression,value) 若是expression不爲null返回expression表達式的值,不然返回value的值
2)聚合函數
avg() -- 平均值 統計時注意null不會被統計,須要加上isnull(列名,0) sum() -- 求和 count() -- 求行數 min() -- 求最小值 max() -- 求最大值
3)字符串操做函數
LEN() --計算字符串長度 LOWER() --轉小寫 UPPER () --大寫 LTRIM() --字符串左側的空格去掉 RTRIM () --字符串右側的空格去掉 LTRIM(RTRIM(' bb ')) LEFT()、RIGHT() -- 截取取字符串 SUBSTRING(string,start_position,length) -- 參數string爲主字符串,start_position爲子字符串在主字符串中的起始位置(從1開始),length爲子字符串的最大長度。 SELECT SUBSTRING('abcdef111',2,3) REPLACE(string,oldstr,newstr) Convert(decimal(18,2),num)--保留兩位小數
4)日期相關函數
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 爲計量單位,可取值參考DateAdd。 -- 獲取日期的某一部分 : DATEPART (datepart,date)--返回一個日期的特定部分 整數 DATENAME(datepart,date)--返回日期中指定部分 字符串 YEAR() MONTH() DAY()
1五、sql語句執行順序
5>…Select 5-1>選擇列,5-2>distinct,5-3>top 1>…From 表 2>…Where 條件 3>…Group by 列 4>…Having 篩選條件 6>…Order by 列
---------------------如下是根據園友建議後續補充的,部分爲項目中的實際代碼(沒時間寫整理直接貼源碼)---------------------------
1六、分組查詢group by...having
對group by分組後的數據進行過濾在分組查詢中,查詢的列名必須出如今group by後或者在聚合函數中
--查詢平均工資大於兩千塊錢的部門 select department_id,avg(wages) from employee where department_id is not null group by department_id having avg(wages)>2000
1七、臨時表[轉]
方法一:
create table #臨時表名(字段1 約束條件,
字段2 約束條件,
.....)
create table ##臨時表名(字段1 約束條件,
字段2 約束條件,
.....)
方法二:
select * into #臨時表名 from 你的表;
select * into ##臨時表名 from 你的表;
注:以上的#表明局部臨時表,##表明全局臨時表
drop table #Tmp --刪除臨時表#Tmp create table #Tmp --建立臨時表#Tmp ( ID int IDENTITY (1,1) not null, --建立列ID,而且每次新增一條記錄就會加1 WokNo varchar(50), primary key (ID) --定義ID爲臨時表#Tmp的主鍵 ); Select * from #Tmp --查詢臨時表的數據 truncate table #Tmp --清空臨時表的全部數據和約束
詳細說明:http://www.cnblogs.com/Hdsome/archive/2008/12/10/1351504.html
1八、表值函數
Create FUNCTION [dbo].[GetUPR] ( @upr varchar(2) --傳入函數中的參數 ) RETURNS @tab TABLE ( UPR varchar(2) --返回表的字段,這裏只有一個字段 ) AS BEGIN if(@upr='0') begin insert @tab select 'U' union select 'P' union select 'R' end else begin insert @tab select @upr end RETURN ; END
1九、標量值函數
-- ============================================= -- 根據訂單號獲取銷售員1的郵箱 -- ============================================= Create FUNCTION [dbo].[GetSalManAEmailByOrderNo] ( @orderNo varchar(16) ) RETURNS varchar(128) AS BEGIN declare @salManAEmail varchar(128) select @salManAEmail=EMailA from UserDB.dbo.EmployeeInfo where EmployeeID in ( select EmployeeInfoID from SalesManInfo where SalesManCode in ( select SalesManA from OrderInfo where SalesOrder=@orderNo ) ) RETURN ( @salManAEmail) END
20、觸發器[轉]
CREATE TRIGGER trigger_name ON {table_name | view_name} {FOR | After | Instead of } [ insert, update,delete ] AS sql_statement
詳細說明:http://www.cnblogs.com/yank/p/4193820.html