T-SQL学习的笔记,以备查阅
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 性别=@gender,@id ----while循环 declare @i int=1 while @i<=100 begin print @i set @i=@i+1 end --计算1-100的和 declare @i int=1 declare @sum int=0 while @i<=100 begin set @sum=@sum+@i set @i=@i+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 @osum=@osum+@j end if @j%2<>0 begin set @jsum=@jsum+@j end set @j=@j+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 @sum=@sum+@@error --确定是否有出错,有则加上 update bank set money=money-10 where id='002' set @sum=@sum+@@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 @num1+@num2 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 @count=@cont 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,@pagecount=@pc output,@tablecount=@pt 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 id=@zid1 --如果有,则返回1,没有则为0 declare @count2 int ----声明一个变量,用来存储是否有收账人编号 select @count2=count(*) from bank where id=@zid2 --如果有,则返回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 id=@zid1 if @money-@decimal>=10 begin --开始转账 begin transaction declare @sum int =0 --1.加钱 update bank set money=money-@decimal where id=@zid1 set @sum=@sum+@@ERROR --2.扣钱 update bank set money=money+@decimal where id=@zid2 set @sum=@sum+@@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',@reslut=@isok 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 班级编号=@id end ----- exec usp_delete_table 1 ----修改(根据班级编号) create proc usp_update_table @name nvarchar(50), @desc nvarchar(500), @id int as begin update [table] set 班级名称=@name,班级描述=@desc where 班级编号=@id 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