SQLServer 学习笔记1

1.分页查询

--分页查询
--查询前两个
select top 2* from #c;
--查询前50%
select top 50 percent * from #c;
--分页,从第三个开始,每页显示2个
/*
ROW_NUMBER() OVER (ORDER BY name1)rownumber
根据name1字段排序生成自定义的rownumber列
rownumber>2 也就是从rownumber=3开始显示
TOP 2* 只显示前两个*/
select top 2* from (select row_number() over(order by name1)rownumber,* from #c)temp 
where rownumber >2;

 over,开窗函数,over关键字表示把聚合函数当成聚合开窗函数而不是聚合函数,例:

select *,count(C#) over() from SC;

SQL 标准允许将所有聚合函数用做聚合开窗函数。

允许返回group by 或者聚合函数内不包含的其他列

over()内可以填写 partition by 类似于group by 分组查询,order by 排序查询

常用的还有 rank() over()排序函数:

select *,rank()over(order by score desc)排名 from SC;

两个99并列第一,而第二名不见了,保留了名次空缺

dense_rank() over()密集排序函数:

select *,dense_rank()over(order by score desc)排名 from SC;

查询各科成绩前三的记录

select * from (select *,rank() over(partition by C# order by score desc)A from SC)B 
where B.A<=3;

partition by C# 按C#分组,order by score desc,按分数降序排序

2.单引号处理

'Chef Anton''s Cajun Seasoning'

结果 Chef Anton's Cajun Seasoning

3.between and 可以用于字符串

select * from Products where ProductName between 'Carnarvon Tigers' 
and 'Mozzarella' order by ProductName;

4.变量 if while case

if else:

--定义一个变量
declare @Country varhcar(20);
--赋值
set @Country = 'Germany';
--查询Country为Germany的信息
select * from Customers where Country = @Country;
--查询CustomerID = 1的Country的值 赋值给@Country
select @Country = Country from Customers where CustomerID =1;
--if else 判断
declare @flag int;
set @flag = 10;
if @flag>5
begin --开始相当于大括号
    print '你好'
end --结束,如果不写,则只能写一条语句,和JAVA等高级语言类似
else
    print 'hello'

while循环

--while 循环
--建表
create table Score (
    Code int primary key,
    Degree int not null,
    Sex varchar(3)
);
--插入数据略。。。
declare @degree decimal(18,2)  --定义一个变量接受最高分
/*
      18:表示定点精度,小数点左边和右边可以存储的十进制数字的最大个数,最大精度为38
      2:表示小数位数,小数点右边可以存储的十进制数字的最大个数。
小数位必须是0~18之间(18是上面规定的定点精度)。默认的小数位是0。
*/ select @degree = MAX(Degree) from Score; --存下最高分 declare @code int; --定义一个变量接收学号 select @code = Code from Score where Degree = @degree; --存下最高分的学号 declare @sex varchar(3); select @sex = Sex from Score where Code = @code; --存入最高分学号对应的学生性别 if @sex = '' print '这是一个男同学' else print '这是一个女同学' while @degree > 90 --while循环 begin print '优秀!' break --打断循环 end

while if 嵌套

declare @degree int;
set @degree = 90;
while @degree <95
begin
    print '考得很好!'
    set @degree = @degree + 1
    if @degree = 93 --当@degree = 93时,跳出循环
        break
end

case when

--建表
create table Student (
   Sid int primary key,
   Age int not null 
);
--数据插入略。。。
select Age,
    case Age
        when 19 then '青年'
        when 18 then '小伙'
        else '少年'
    end
from Student;

 case when也可用于判断条件,例如 case when score >=60 then 1 else 0

select C#,(convert(decimal(5,2),sum(case when score >=60 then 1 else 0 end)*1.00/count(*))*100)及格率 from SC group by C#;

sum(case when score >=60 then 1 else 0 end),score >=60计1否则计0,计算总和,也就是算出了各科分数>=60的人数,*1.00转为浮点数,然后/count(*),除以总人数,得出比率,*100得出百分比

5.触发器

触发器有:

1.after 执行语句之后触发

2.insert 插入数据时触发

3.update 更新数据时触发

4.delete 删除数据时触发

5.instead of 执行语句之前触发:as 后的语句会替代原来执行的语句,原语句并不会被真正执行,例如:

alter trigger trigger_学生_Delete 
on 学生
instead of Delete
as 
begin 
select 学号, 姓名 from deleted
end 
delete from 学生 where 学号 = 4

上例中定义了“trigger学生_Delete”触发器,该触发器从“delete”表中打印出所要删除的学生.在执行“delete”操作后,会发现“学号 = 4”的学生并未被删除, 原因在于“trigger学生Delete”替代了所要执行的“delete from 学生 where 学号 = 4”语句,而在“trigger学生_Delete”中并未真正删除学生。

注意:inserted deleted 两张虚拟表分别存入插入、修改 更新前、被删除的数据

表结构与触发器应用的表结构相同

触发器完成工作后,这两张表会被删除

(1)insert触发器

--建表
create table Classes (
   ClassID int primary key,
   ClassName varchar(20) not null,
   Counts int not null  
);
--判断触发器是否存在,有则删除
if(object_id('tgr_classes_insert','TR')is not null)
drop trigger tgr_classes_insert
go
--创建触发器,每当一条数据被插入时,会另外再插入一条数据
create trigger trg_classes_insert
on Classes --触发器应用于Classes表
for inert --插入数据时触发
as
--定义变量
declare @Cid int,@Cname varchar(20),@Count int;
--在inserted表中查询已插入的信息,并给变量赋值
select @Cid = ClassID+1,@Cname = ClassName,@Counts = Counts +3 from inserted;
insert into Classes --插入数据
values (
           @Cid,
           --将Cid转为varchar,同时截取‘班’(截取下标基于1,截取长度),+号执行字符串拼接
           convert(varchar,@Cid)+substring(@Cname,2,1),
           @Counts
          )    
print '添加数据成功'
go
--该触发器的的作用就是Classes表插入数据时,会再向表中插入一条数据,
实用情况下,可以再向一张表插入数据时,同时给另一张表也插入一条数据
insert into Classes values(1,'1班',20);--触发器被触发

(2)delete触发器

--删除数据时备份
if(object_id('tgr_classes_delete','TR')is not null)
drop trigger tgr_classes_delete
go
create trigger tgr_classes_delete
on Classes
for delete
as 
print '备份数据中...'
if(object_id('ClassesBackUp','U')is not null)
--如果有备份表,直接插入数据
--将deleted表中的数据复制
insert into ClassesBackUp select * from Deleted;
--如果没有备份表,创建表再插入数据
else
select * into ClassesBackUp from Deleted;
print '备份数据成功!'
go
delete Classes where ClassID = 2;--delete触发器执行
select * from Classes;
select * from ClassesBackUp;

查询某个表的触发器有哪些:

select * from sysobjects where xtype = 'TR' and parent_obj = object_obj('tablename');

查询当前数据库内有哪些触发器:

select * from sysobjects where xtype = 'TR'

PS 复制表数据、结构常用语句

1.复制旧表的数据到新表(假设两个表结构一样)

INSERT INTO 新表 SELECT * FROM 旧表
2.复制表结构及数据,自动创建表
select * into 新表 from 旧表
select * into 新表 from 旧表 where 1=2;只生成表结构
 

 

posted @ 2018-07-12 12:01  0==1&1==0  阅读(763)  评论(0编辑  收藏  举报