T-SQL學習的筆記,以備查閱
阿新 • • 發佈:2018-11-21
create database MyDatabseOne; --建立資料庫 drop database MydatabaseOne; --刪除資料庫; --如果直接點"執行"將是執行所有語句,而選中某些則是單獨執行 --以下程式碼建立資料庫的初始值 create database MydatabaseOne --建立資料庫 on primary ( --配置主資料檔案 name='MydatabaseOne', --主資料檔案的邏輯名稱 filename='C:\Users\Rao\Desktop\MydatabaseOne.mdf', --主資料的實際儲存路徑 size=3mb, --主資料的初始大小 maxsize=100mb, --主資料庫的最大大小 filegrowth=20% --主資料庫每次增長的大小(最後一個可以不用逗號) ) log on ( name='MydatabaseOne_log', filename='C:\Users\Rao\Desktop\MydatabseOne_log.ldf', size=1mb, filegrowth=1mb ) --建一表,為員工表 use School create table Employess ( EmpID int identity(1,1) not null, EmpName nvarchar(50) not null, EmpGender nchar(1) not null, EmpAge int, EmpJoinDate date, EmpPhone nvarchar(11) not null ) --另一表,部門,將引 create table Department ( DepID int identity(1,1) not null, DepName nvarchar(50) not null ) --閱表 select * from Department select * from Employess --增之為Dep insert into Department values('中國市場研發部') --增之為Emp insert into Employess values('Heil','女',28,'2016-12-31','12345678901') --刪其一列 --自動編號 set identity_insert Department on insert into Department(DepID,DepName) values(3,'erro') set identity_insert Department off --修改 update Employess set empage=28,EmpJoinDate='2017-01-01',EmpPhone='159357852' where EmpName='Heil' --以條件刪,無則全刪,如需高效,truncate table Department delete from Department where DepName='erro' --刪列 alter table Employess drop column EmpJoinDate --增列 alter table Employess add EmpJoinDate nvarchar(50) --修改資料型別 alter table Employess alter column EmpPhone nvarchar(20) --增列主鍵約束 alter table Employess add constraint PK_Employess_EmpID primary key(EmpID) --增非空約束 alter table Employess alter column EmpAge nvarchar(20) not null --增唯一約束 alter table Employess add constraint UQ_Employess_EmpName unique(EmpName) select * from Employess delete from Employess where EmpName='Heil' --增加預設約束 alter table Employess add constraint DF_Employess_EmpGender default('男') for EmpGender --增加檢查約束 alter table Employess add constraint CK_Employess_EmpGender check(EmpGender='男' or EmpGender='女') alter table Employess add constraint CK_Employess_EmpAge check(EmpAge>18 or EmpAge<=35) select * from Employess update Employess set empIDCard='123456789111111' alter table Employess add EmpIDCard nvarchar(18) alter table Employess alter column EmpIDCard nvarchar(18) not null alter table Employess add constraint CK_Employess_EmpIDCard check(len(EmpIDCard)=15 or len(EmpIDCard)=18) --主鍵約束 alter table Department add constraint PK_Department_DepID primary key(DepID) --外來鍵約束 alter table Employess add DepID int update Employess set DepID=1 alter table Employess alter column DepID int not null alter table Employess add constraint FK_Employess_Department foreign key(EmpID) references Department(DepID) --棄約 alter table Employess drop constraint CK_Employess_EmpIDCard, FK_Employess_Department --多增約束 alter table Employess add constraint FK_Employess_Department foreign key(EmpID) references Department(DepID), constraint CK_Employess_EmpIDCard check(len(EmpIDCard)=15 or len(EmpIDCard)=18) ---------------查詢 ---查詢整表 --*號為所有行所有列均查詢 select * from TblStudent --查詢某些列 select tsid,tsname,tsgender from TblStudent --條件查詢行 select tsid,tsname,tsgender from TblStudent where tSClassId=2 --為查詢結果的列起別名(as一般情況可省略,但如果列名中有非法字元,可用引號將別名引起來'(學生編號)', --或者可以 學生編號=tsid --也可隨意增加一個別名列如 婚否='否') select tsid as 學生編號, tsgender as 性別, tsphone as 聯絡電話 from TblStudent select 當前時間=GETDATE() --去除查詢結果中的重複項(distinct只能去除查詢結果之後的重複) select distinct tsname,tsgender from TblStudent ---------排序 --按照年齡,降序(desc)升序為(asc ,空會在最前,預設不寫為升序) select *from TblStudent order by tSage desc --查詢年齡最小的前3個 select top 3 * from TblStudent order by tsage --表示式需要() select top (1+3) * from TblStudent order by tsage --取前百分比(如不為整數,則向上取整,例如3.0取3,而3.1%取4) select top 3 percent *from TblStudent order by tsage -----聚合函式,不統計空值 --查詢最大值 select max(tsage) from TblStudent --查詢最小值 select min(tsage) from TblStudent --查詢總和 use School select sum(tsage) from TblStudent --統計多少條資料(*可以為任意值,空不統) select count(*) from TblStudent where tSClassId=1 --平均值 select avg(tsage*1.0) from TblStudent select 年齡最大=max(tsage),年齡最小=min(tsage),平均年齡=avg(tsage),總條數=count(tsage) from TblStudent select * from TblStudent --between and 等價於 and select tsname from TblStudent where tSage between 13 and 17 select tsname from TblStudent where tsage>=13 and tsage<=17 --in 等價多or 但如果查詢的是如(3,4,5)此類連續資料,可以直接tsclassid>3 and tsclassid<5,此法更高效 select * from TblStudent where tSClassId in (1,3,30) ---模糊查詢- _ % ^ [] ([-]篩選範圍) -- _ 表示任意單個字元 select * from TblStudent where tSName like '張_' -- % 任意多個任意字元 select * from TblStudent where tSName like '張%' --查詢所有帶%(注:%是一個萬用字元,所以需要用[]轉義)的資料 select * from TblStudent where tSName like '%[%]%' --自定義轉義符(例中指定\後為轉義字元,其後的緊跟字元為普通字元,不再是系統預設 select * from TblStudent where tSName like '%\[%' escape '\' use School select * from TblStudent select * from TblStudent where tSAddress=null --查詢空值,以is null / not null 僅針對數值型別,字串型別如為空則不為null select * from TblStudent where tSAddress='null' --任何值和null計算後所得結果亦為null select 2000+null ---通過order by排序,一定要在整個SQL語句的最後(在where之前) --降序用desc ,升序用asc(亦可為空) select tsage from TblStudent order by tsage desc select * from TblStudent --雙降序 select * from TblStudent order by tsage desc,tSClassId --統計每個ID下的人數 select 班級ID=tsclassid,班級人數=count(*) from TblStudent group by tSClassId select 性別=tsgender,人數=count(*) from tblstudent group by tsgender --統計班級中id下男同學的個數 --使用group by(當使用了此分組語句時,不能再包含其它列的查詢,除非此列也出現在聚合函式中) select 班級ID=tsclassid,男同學人數=count(*) from TblStudent where tSGender='男' group by tSClassId use School select 班級ID=tsclassid,男同學人數=count(*),男同學平均年齡=AVG(tsage) from TblStudent where tSGender='男' group by tSClassId ----having與where的區別,where以什麼進行分組,而having是分組之後進行篩選 ---只保留班級人數大於1的 select 班級ID=tsclassid, 班級人數=count(*) from TblStudent group by tSClassId having count(*)>1 select '100+1100' -------------型別轉換函式------------ --cast cast(原資料 as 新型別) select 100.0+cast('1000' as int) --convert(資料型別,原資料) select 100.0+convert(int,'1000') select '您的班級編號:'+convert(char(1),1) -----聯合union---- --聯合的資料列的型別必須一致 --union all 不會對聯合的資料去除重複,並且不會排列 --union 會去除重複,並且排列 --大多數的時候不需要去除重複,也並不需要重新排列,所以一般建議使用union all select tsname,tSId from TblStudent --union all select ttname,tTId from TblTeacher ----使用union all插入資料 select * from TblTeacher insert into TblTeacher select '李四',0,30,4000,'1986-1-1' union all select '王五',0,30,4000,'1986-1-1' select '李四',0,30,4000,'1986-1-1' union all select '王五',0,30,4000,'1986-1-1' ------備份表------ use School ----從TblStudent表查詢所有列並插入到一張新表中 ----約束不會複製 select * into TblStudent2017 from TblStudent select * from TblStudent2017 drop table TblStudent2017 ----只複製表結構 select top 0 * into TblStudent2017 from TblStudent ----向表中追加資料 insert into TblStudent2017 values('date','男','湖北','13855968545',26,'1991-12-15',1,1) select * from TblStudent ---追加資料 insert into TblStudent2017 select tsname,tsgender,tsaddress,tsphone,tsage,tsbirthday,tSCardId,tsclassid from TblStudent where tSGender='女' -------------------常用字串函式-------------. ------1.計算字元的個數 print len('HI,how are you') ------2.返回所佔用的位元組的個數,非字串 print datalength('HI') ------3.upper(),lower(),大小寫 print upper('hi') print lower('HI') ------4.去掉兩端空格ltrim()去掉左端,rtrim()去掉右端空格 print '==========='+rtrim(ltrim(' Hello '))+'===============' ------5.字串擷取函式 print left('hihihi',2) print right('hihiii',2) print substring('abcdefg',1,1) --下標從1開始,如果下標小於1,則往前會推一個空值 -----------日期函式-------- print getdate() print sysdatetime() ----dateadd()增加時間 ---增加天數,100天,從當前時間 month 月 year 年 minute分鐘 second秒 hour小時 print dateadd(day,100,getdate()) -----查詢大於30歲的人 select * from TblStudent select * from TblStudent where dateadd(year,30,tSBirthday)<=GETDATE() --datediff()計算 兩個日期 的差 print datediff(year,'1990-12-15',getdate()) print today() ---計算學生年齡 select * from TblStudent select *, 年齡=DATEDIFF(year,tsbirthday,getdate()) from TblStudent select 年齡=DATEDIFF(year,tsbirthday,getdate()),人數=count(*) from TblStudent group by DATEDIFF(year,tsbirthday,getdate()) ----獲取日期部分 print datepart(year,getdate()) print datepart(dayofyear,getdate()) --獲取自開始至目前的天數 ---datename() print datename(year,getdate()) --同樣打印出當前年,但不同於以上,此為列印的字串形式,無法進行與其它數值型別計算 ----*不在要表中,無法執行-- ----計算本月呼叫員撥打電話的時間,取前三名 select * from CallRecords top 3 --取前三名 呼叫員編號=CallNumber, 呼叫員時長=datediff(second,starttime,endtime) where datediff(month,satarttime,endtime)=0 --表示本月 group by CallNumber --按照呼叫員來分組 order by 呼叫員時長 desc --以呼叫員時長排序,降序 select * from TblStudent delete from TblStudent where tsname='vs2015' update TblStudent set tSName='吳廣' where tSName='weweew' select tsname from tblstudent select * from person insert into person values('測試','男',18) select count(*) from person select * from usertable select count(*) from usertable where username='admin' and userpwd='admn' insert into person select 'add','男',21 union all select 'add','男',21 union all select 'add','男',21 union all select 'add','男',21 use school select * from person -----獲得剛剛插入語句的自動編號 insert into person output inserted.PId values('ggg','男',30) select * from UserTable select * from usertable where username='aa' or 1=1;insert into UserTable values('ggg','ggg') --' select * from usertable where username='aa' or 1=1;insert into UserTable values('ggg','ggg','ggg') --' select count(*) from usertable where username='admin' and userpwd='admin' insert into Person(PName,PGender,PAge) values('dsfkjds','男',30) update Person set PName='111' where PId=2 select count(*) from UserTable select * from NoteBookList where NParentID=-1 select dConet from book where dName='C#從入門到精通' select * from book insert into book values(14,'盛世婚寵','2017-03-25','2616','2017-03-25',0) use School select * from UserTable select * from Phonegroup select * from PhoneNumber --內連線查詢 select pname,pgender,phone,pgroup from PhoneNumber join Phonegroup on phoneGroup.pid=phonenumber.parentid select * from Person use school select PhoneNumber.pid,pname,pgender,page,phone,pgroup,PhoneGroup.PId from PhoneNumber join Phonegroup on phoneGroup.pid=phonenumber.parentid ---case的用法---- ----相當於C#中的if else 此項可以區間判斷 --then後面的資料型別全部必須一致 select * , 級別=case when Level=1 then '菜鳥' when level=2 then '老鳥' when level=3 then '烤雞' else '骨灰' end from BBSLevel --相當於C#中的switch 此項只能等值判斷 select * , 級別=case level when 1 then '菜鳥' when 2 then '老鳥' when 3 then '烤雞' else '骨灰' end from BBSLevel --練習 select ttname, ttage, tTSalary, 工資級別=case ttsalary/1000 when 1 then '水貨' when 2 then '一般' when 3 then '還行' when 4 then '不錯' else '牛人' end from TblTeacher create table TestA ( A int, B int, C int ) insert into testA values(10,20,30) insert into testA values(20,30,10) insert into testA values(30,10,20) insert into testA values(10,20,30) select * from TestA --A列大於B列顯示A列值,B列大於C列顯示C列的值 select X=case when A>B then A else B end, Y=case when B>C then C else C end from TestA create table test ( number varchar(10), amount int ) insert into test(number,amount) values('RK1',10) insert into test(number,amount) values('RK1',20) insert into test(number,amount) values('RK1',-30) insert into test(number,amount) values('RK1',-10) select 單號=number, 收入=case when amount>0 then amount else 0 end, 支出=case when amount<0 then abs(amount) else 0 end from test select * from teamscore select 隊名=teamName, 勝=sum(case when gameresult='勝' then 1 else 0 end), 負=sum(case when gameresult='負' then 1 else 0 end) from teamscore group by teamname select * from nbascore select 隊伍名稱=teamName, 第1賽季得分=sum(case when seasonname='第1賽季' then score end), 第2賽季得分=sum(case when seasonname='第2賽季' then score end), 第3賽季得分=sum(case when seasonname='第3賽季' then score end) from nbascore group by teamName ---分頁查詢-- --row_number() over () select * from TblStudent2017 ---確定以年齡升序排序進行編號 select *,rn=ROW_NUMBER() over (order by tsage asc) from TblStudent2017 --將編好號的查詢語句當子查詢語句進行查詢 --每頁3條,查詢第3頁為 (3-1)*3+1 至 3*3 select * from (select *,rn=ROW_NUMBER() over (order by tsage asc) from TblStudent2017) as t where t.rn between (3-1)*1+1 and 3*3 select count(*) from TblStudent2017 . SELECT * FROM Person ------------------------TSQL程式設計----------- --1.宣告變數 declare @name nvarchar(50) declare @age int declare @gender nchar(1),@id int --2.為變數賦值 set @name='xxoo' select @age=18 select @gender='男',@id=1 --3.輸出 select 姓名= @name select 年齡= @age select 性別[email protected],@id ----while迴圈 declare @i int=1 while @i<=100 begin print @i set @[email protected]+1 end --計算1-100的和 declare @i int=1 declare @sum int=0 while @i<=100 begin set @[email protected][email protected] set @[email protected]+1 end print @sum --計算1-100之間所有整奇數與偶數的和 declare @j int=1 declare @jsum int=0 declare @osum int=0 while @j<=100 begin if @j%2 =0 begin set @[email protected][email protected] end if @j%2<>0 begin set @[email protected][email protected] end set @[email protected]+1 end print @osum print @jsum --一般情況下兩個@@是系統變數,但如果是手動宣告的,則為全域性變數 print @@LANGUAGE ---------事務 --轉賬示例 select * from bank begin transaction declare @sum int =0 --宣告變數用來儲存如果出錯的條數 update bank set money=money+10 where id='001' set @[email protected][email protected]@error --確定是否有出錯,有則加上 update bank set money=money-10 where id='002' set @[email protected][email protected]@error if @sum<>0 --如果不等於0,則有出錯 begin rollback --讓所有操作回滾 end else begin commit --提交所有操作 end ---------------儲存過程 ------------相當於方法 --------1.無參無返回值的 create proc usp_select_tblteacher_salary as begin select * from TblTeacher where tTSalary>2000 end --呼叫儲存過程 exec usp_select_tblteacher_salary -----2.帶引數的儲存過程 create proc usp_add @num1 int, @num2 int as begin select @[email protected] end --呼叫 exec usp_add 100,1 ---帶返回值的(輸出引數) alter proc usp_count @count int output as begin set @count=(select count(*) from TblStudent) end --呼叫 declare @cont int exec usp_count @[email protected] output print @cont ---構建分頁查詢的儲存過程 alter proc usp_bank @pagesize int=7, --每頁顯示條數 @pageindex int=1, --當前檢視第幾頁的記錄 @pagecount int output, --總條數 @tablecount int output --總頁數 as begin select * from (select *,rn=ROW_NUMBER() over(order by Money asc) from bank) as t where t.rn between (@pageindex-1)*@pagesize+1 and @pageindex*@pagesize --計算記錄的總條數 set @pagecount=(select count(*) from bank) --計算總頁數,向上取整 set @tablecount=CEILING(@pagecount*1.0/@pagesize) end -----C#dal呼叫 public List<NewListMl> PageFromProc(int pageIndex,int pageSize,string typeID,out int total) { SqlParameter pi = new SqlParameter("@pageIndex", pageIndex); SqlParameter ps = new SqlParameter("@pageSize", pageSize); SqlParameter ti = new SqlParameter("@tyID", typeID); SqlParameter to = new SqlParameter("@total", System.Data.SqlDbType.Int); to.Direction = System.Data.ParameterDirection.Output; SqlParameter[] pms = { pi,ps,ti,to }; //呼叫方法得到資料 List<NewListMl> list= GetListModel("LoadPage", System.Data.CommandType.StoredProcedure, pms); //得到儲存過程輸出的總條數 total = (int)to.Value; return list; } declare @pc int declare @pt int exec usp_bank @pagesize=6,@pageindex=5,@[email protected] output,@[email protected] output print @pc print @pt --------------------------------------------set與select的區別 declare @a int --set @a=(select count(*) from bank) select @a=count(*) from bank print @a ----當查詢語句得到多個值的時候,則set會報錯,而select會得到最後一個查到的值 declare @a int --set @a=(select money from bank) select @a=money from bank print @a --------------------------------------------轉賬示例(儲存過程+事務) alter proc usp_zz @decimal int ,--轉出/收到錢數 @zid1 nvarchar(4), --轉賬編號 @zid2 nvarchar(4), --/收賬人編號 @reslut int output --判斷是否轉賬成功,1,表示成功,2.表示失敗,3.表示餘額不足,4,表示不存在轉賬的id as begin -------判斷是否存在編號 declare @count1 int --宣告一個變數,用來儲存是否有收賬人編號 select @count1=count(*) from bank where [email protected] --如果有,則返回1,沒有則為0 declare @count2 int ----宣告一個變數,用來儲存是否有收賬人編號 select @count2=count(*) from bank where [email protected] --如果有,則返回1,沒有則為0 if @count1<>1 or @count2<>1 --判斷其值是否1,有一個不為1,則為false,此處為為false begin set @reslut=4 --為false,則有一個編號是沒有,即返回4 end else --如果有,則繼續以下程式碼 begin --1.判斷金額是否足夠 declare @money int select @money=money from bank where [email protected] if @[email protected]>=10 begin --開始轉賬 begin transaction declare @sum int =0 --1.加錢 update bank set [email protected] where [email protected] set @[email protected][email protected]@ERROR --2.扣錢 update bank set [email protected] where [email protected] set @[email protected][email protected]@ERROR --3.判斷是否成功 if @sum<>0 begin set @reslut=2 --轉賬失敗 rollback end else begin set @reslut=1 --轉賬成功 commit end end else begin set @reslut=3 --餘額不足 end end end -------------------------------------------------------------------------- declare @isok int exec usp_zz @decimal= 20,@zid1= '004',@zid2='001',@[email protected] output print @isok select * from bank select count(*) from bank where id='001' declare @count1 int select @count1=count(*) from bank where id='001' print @count1 declare @count2 int select @count2=count(*) from bank where id='002' print @count2 declare @isok int if @count1<>1 or @count2<>1 begin set @isok=0 end else begin set @isok=1 end print @isok ---------------------------------------------------------------------- --------------增刪改查的儲存過程封裝----------------------------- -----以Table表為例 --select * from [Table] ----增加 create proc usp_insert_table @name nvarchar(50), @desc nvarchar(500) as begin insert into [Table] values(@name,@desc) end ------ exec usp_insert_table '高二一班','這是我第一個新建的' -----刪除(根據班級編號) create proc usp_delete_table @id int as begin delete from [table] where 班級編號[email protected] end ----- exec usp_delete_table 1 ----修改(根據班級編號) create proc usp_update_table @name nvarchar(50), @desc nvarchar(500), @id int as begin update [table] set 班級名稱[email protected],班級描述[email protected] where 班級編號[email protected] end ---- exec usp_update_table '高二二班','這是我修改過的',1 ---查詢 create proc usp_select_table as begin select * from [table] end -- 讓欄位區分大小寫查詢 設計表,選中相應的欄位,排序規則中,選擇區分大小寫 --去除重複 DELETE t FROM (SELECT *,ROW_NUMBER()OVER(PARTITION BY title ORDER BY RAND()) AS RN FROM BookInfo) AS t WHERE RN>1 給每行某欄位新增100內的隨機數 UPDATE BookInfo SET BookInfo.count = CEILING(rand(checksum(newid()))*100) --獲取所有表名 select table_name,table_type from INFORMATION_SCHEMA.TABLES --獲取指定表的欄位名和欄位資料格式 --獲取指定表的欄位名和欄位資料格式 select column_name,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH,IS_NULLABLE from INFORMATION_SCHEMA.COLUMNS t where t.TABLE_NAME='Users' --獲取所有資料庫名稱 select name from master..sysdatabases where name not in('master','model','msdb','tempdb') --獲取指定資料庫中的所有表 use BookStore select table_name from INFORMATION_SCHEMA.TABLES --查詢空("或NULL")資料 select * from tb_table where filed is null or filed = '' --查詢銷售量佔前50%的圖書資訊 select top 50 percent 書名,書號,sum(銷售數量) as 合計銷售數量 from tb_Book group by 書號,書名,作者 order by 3 desc --判斷是否為數值 select 姓名,isnumeric(年齡) from tb_Student --在查詢時對數值進行取整 select dm as 數值取整前,ceiling(dm) as 數值取整後 from tb_money 注:還有 Floor函式 Round(dm,2)四捨五入,2為保留的小數位數 ABS(求絕對值) --在查詢中生成隨機數 select floor(rand()*50) 示例:select * from tb_Student where 學生編號=22050110+floor(rand()*10) --隨機生成大於0小於1的小數數值後與10相乘,並對小數數值向下取整 --實現字串的大小寫轉換 select friendname as 字串 lower(friendname) as 全部轉小寫,upper(friendname) as 全部轉大寫 from tb_string --返回字元在字串中出現的次數 select friendname as 字串 (len(friendname)-len(replace(friendname,'i','')))/len('i') as 出現指定字元的次數 from tb_string --其它各類函式 substring(str,index,lenght) --同C# stuff(str,index,lenght,'del') --刪除指定長度的字元 select ABS(-12), --求絕對值 CEILING(12.3), --向上取整 FLOOR(12.3), --向下取整 ROUND(12.333,1), --四捨五入,第二個引數為保留的位數 RAND()*10, --隨機數,生成0-1隨機浮點數 SIGN('11.3'), --判斷指定資料列中的數值是否為正數(返回1),負數(返回-1),0(返回0) SIGN(1) LOWER('HELLO'), --小寫 UPPER('hello'), --大寫 SUBSTRING('電腦科學與技術',2,3), --擷取指定字串從第2位開始共擷取3個字元 STUFF('電腦科學與技術',2,3,'11'), --相當於替換了,此例將算機科替換成了11,如果替換成空,則會刪除 CHARINDEX('學與','電腦科學與技術'), --查詢字串在另一字串中的初始位置 REPLACE('電腦科學與技術','機科','科機'), --替換 ISDATE('1992/2/22'), --判斷是否日期,是則返回1 YEAR('1992/2/22'),MONTH('1992/2/22'),DAY('1992/2/22') --分別返回年,月日 select DATENAME(weekday,getdate()), --返回當前的星期 DATEDIFF(YEAR,'1992/02/22',getdate()) --計算年齡,中間出生日期的引數只用符合datetime即可,例如19920222