MSSQL复习笔记(上)
什么是SQL语句
sql语言:结构化的查询语言。(Structured Query Language),是关系数据库管理系统的标准语言。
它是一种解释语言:写一句执行一句,不需要整体编译执行。
语法特点:
1.没有“ ”,字符串使用‘ ’包含
2.没有逻辑相等,赋值和逻辑相等都是=
3.类型不再是最严格的。任何数据都可以包含在‘ ’以内
4.没有bool值的概念,但是在视图中可以输入true/false
5.它也有关系运算符:> < >= <= = <> != ,它返回一个bool值
6.它也有逻辑运算符: !(not) &&(and) ||(or)
7.它不区别大小写
使用sql语句创建数据库和表
语法:
create database 数据库名称 |
–判断数据库文件是否已经存在 :数据库的记录都存储在master库中的sysdatabases表中
–自动切换当前数据库
–使用代码开启外围应该配置器
exec sp_configure 'show advanced options' ,1 |
–自定义目录 xp_cmdshell可以创建出目录 ‘mkdir f:\project’:指定创建目录
exec xp_cmdshell 'mkdir f:\project' |
–exists 函数判断()中的查询语句是否返回结果集,如果返回了结果集则得到true,否则得到false
if exists( select * from sysdatabases where name='School') |
–创建文件组
filegroup mygroup |
创建数据表
语法:
create table 表名 |
创建老师表Teacher :Id、Name、Gender、Age、Salary、Birthday
use School |
数据完整性约束
实体完整性:实体就是指一条记录。这种完整性就是为了保证每一条记录不是重复记录。是有意义的
– 主键:非空和唯一.一个表只有一个主键,但是一个主键可以是由多个字段组成的 组合键
– 标识列:系统自动生成,永远不重复
– 唯一键:唯一,但是可以为null,只能null一次
域完整性:域就是指字段,它是为了保证字段的值是准和有效,合理值
– 类型 是否null,默认值,check约束,关系
自定义完整性:
– check约束 , 存储过程 触发器
引用完整性:一个表的某个字段的值是引用自另外一个表的某个字段的值。引用的表就是外键表,被引用的表就是主键表
– 1.建立引用的字段类型必须一致
– 2.建立引用的字段的意义一样
– 3.建立主外键关系的时候选择 外键表 去建立主外键关系
– 4.建立主外键关系的字段在主表中必须是主键或者唯一键
– 5.对于操作的影响 :
– 1.在添加数据时,先添加主键表再添加外键表数据
– 2.在删除的时候先外键表数据再删除主键表数据
– 级联的操作:不建议使用:会破坏数据完整性
– 不执行任何操作:该报错就报错,该删除就删除
– 级联:删除主表记录,从表引用该值的记录也被删除
– 设置null:删除主表记录,从表对应的字段值设置为null,前提是可以为null
– 设置为default:删除主表记录,从表对应的字段值设置为default,前提是可以为default
主键约束(PK Primary key) 唯一键约束(UQ unique) 外键约束(FK foreign key) 默认值约束(DF default) check约束(CK check)
语法:
alter table 表名 |
–为id添加主键
alter table teacher |
–on delete set default 级联操作
–不执行任何操作:该报错就报错,该删除就删除 –no action –默认选择
–级联:删除主表记录,从表引用该值的记录也被删除 –cascade
–设置null:删除主表记录,从表对应的字段值设置为null,前提是可以为null –set null
–设置为default:删除主表记录,从表对应的字段值设置为default,前提是可以为default –set default
四中基本字符类型说明
--len(参数) --获取指定参数内容的字符个数 |
SQL基本语句
数据插入
调用方法 一 一对应原则:类型对应,数量对应,顺序对应
语法: 形参 实参
insert into 表名([字段列表]) values(值列表) –数据必须要符合数据完整性
插入操作是单个表的操作
插入操作insert一次只能插入一条记录
use School
–插入teacher所有字段的数据.如果在表后没有指定需要插入的字段名称,那么就默认为所有字段添加值
–但是一定需要注意的是:标识列永远不能自定义值–不能人为插入值
–仅当使用了列列表并且 IDENTITY_INSERT 为 ON 时,才能为表’Teacher’中的标识列指定显式值。
i
nsert into Teacher values('张三',5,1,30,4000,'1984-9-11') |
–不为可以为null的字段插入值 :可以null的字段可以不赋值
–列名或所提供值的数目与表定义不匹配
insert into Teacher(Name,ClassId,Gender,Age,Salary) values('李四',5,1,30,4000) |
–为有默认值的字段插入值:
–1.不写这一列让系统自动赋值
insert into Teacher(Name,ClassId,Gender,Age) values('王五',5,1,30) |
–指定 null或者default
insert into Teacher(Name,ClassId,Gender,Age,Salary,Birthday) values('赵六',5,1,30,default,null) |
–数据必须完全符合表的完整性约束
insert into Teacher(Name,ClassId,Gender,Age,Salary,Birthday) values('赵六1',5,1,300,default,null) |
–任意类型的数据都可以包含在’’以内, 不包括关键字
insert into Teacher(Name,ClassId,Gender,Age,Salary,Birthday) values('马鹏飞','5','0','15',default,null) |
–但是字符串值如果没有包含在’’以内.会报错 列名 ‘兰鹏’ 无效。
insert into Teacher(Name,ClassId,Gender,Age,Salary,Birthday) values('兰鹏','5','0','15',default,null) |
–但是数值组成的字符串可以不使用’’包含
insert into Teacher(Name,ClassId,Gender,Age,Salary,Birthday) values(123,'5','0','15',default,null) |
–日期值必须包含在’‘以内,否则就是默认值
insert into Teacher(Name,ClassId,Gender,Age,Salary,Birthday) values('邹元标2','5','0','15',default,'1991-9-11') |
数据删除
语法:
delete [from] 表名 where 条件 |
–特点:
–1.删除是一条一条进行删除的
–2.每一条记录的删除都需要将操作写入到日志文件中
–3.标识列不会从种子值重新计算,以从上次最后一条标识列值往下计算
–4.这种删除可以触发delete触发器
–truncate table 表名 –没有条件,它是一次性删除所有数据
–特点:
–1.一次性删除所有数据,没有条件,那么日志文件只以最小化的数据写入
–2.它可以使用标识列从种子值重新计算
–3.它不能触发delete触发器
truncate table teacher
数据更新(数据修改):一定需要考虑是否有条件
语法:
update 表名 set 字段=值,字段=值 。。where 条件
update Teacher set Gender='true' |
–修改时添加条件
update Teacher set Gender=0 where Id=20 |
–多字段修改
update Teacher set ClassId=4,Age+=5,Salary=5000 where Id=22 |
–修改班级id=4,同时年龄》20岁的人员工资+500
update Teacher set Salary=Salary+500 where ClassId=4 and Age>20 |
数据检索–查询
语法: *代表所有字段
select */字段名称列表 from 表列表
select StudentNo,StudentName,Sex,[Address] from Student |
–可以为标题设置 别名,别名可以是中文别名
select StudentNo as 学号,StudentName 姓名,性别=Sex,[Address] from Student |
–添加常量列
select StudentNo as 学号,StudentName 姓名,性别=Sex,[Address] ,国籍='中华人民共和国' from Student |
–select的作用
–1.查询
–2.输出select 1+1
–+是运算符,系统会自动为你做类型转换select 1+'1'
select '1'+1
–如果+两边都是字符串,那么它就是一字符串连接符select '1'+'1'
select 'a'+1
–可以输出多列值select 1,2,34,3,545,67,567,6,7
–Top、Distinctselect * from Student
–top可以获取指定的记录数,值可以大于总记录数.但是不能是负值select top 100 * from Student
–百分比是取ceiling()select top 10 percent * from Student
–重复记录与原始的数据表数据无关,只与你查询的结果集有关系 distinct可以去除结果集中的重复记录–结果集中每一列的值都一样
select distinct LoginPwd,Sex,Email from Student |
–聚合函数:
–1.对null过滤
–2.都需要有一个参数
–3.都是返回一个数值
–sum():求和:只能对数值而言,对字符串和日期无效
–avg():求平均值
–count():计数:得到满足条件的记录数
–max():求最大值:可以对任意类型的数据进行聚合,如果是字符串就比较拼音字母进行排序
–min():求最小值
–获取学员总人数
select COUNT(*) from Student
–查询最大年龄值
select MIN(BornDate) from Student |
–查询总分
select SUM(StudentResult) from Result where StudentNo=2 |
–平均分
select avg(StudentResult) from Result where SubjectId=1 |
–注意细节:
select SUM(StudentName) from Student |
–查询学号,姓名,性别,年龄,电话,地址 —查询女生
select StudentNo,StudentName,Sex,BornDate,Address from Student where Sex='女' and BornDate >'1990-1-1' and Address='广州传智播客' |
–指定区间范围
s
elect StudentNo,StudentName,Sex,BornDate,Address from Student where BornDate >='1990-1-1' and BornDate<='1993-1-1' |
–查询班级id 1 3 5 7的学员信息
select * from Student where ClassId=1 or ClassId=3 or ClassId=5 or ClassId=7 |
–指定具体的取值范围–可以是任意类型的范围.值的类型需要一致–可以相互转换
select * from Student where ClassId in(1,3,'5',7) |
–带条件的查询-模糊查询– 只针对字符串而言
–查询 姓 林 的女生信息
–=是一种精确查询,需要完全匹配
select * from Student where Sex='女' and StudentName='林' |
–通配符–元字符
–%:任意个任意字段 window: 正则表达式 :.
–_:任意的单个字符
–[]:代表一个指定的范围,范围可以是连续也可以是间断的。与正则表达式完全一样[0-9a-zA-Z].可以从这个范围中取一个字符
–[^]:取反值
select * from Student where Sex='女' and StudentName='林%' |
–通配符必须在模糊查询关键的中才可以做为通配符使用,否则就是普通字符
–like 像 。。。。一样
select * from Student where Sex='女' and StudentName like '林%' |
–[]的使用 学号在11~15之间的学员信息
select * from Student where StudentNo like '[13579]' |
—处理null值
–null:不是地址没有分配,而是不知道你需要存储什么值 所以null是指 不知道。但是=只能匹配具体的值,而null根本就不是一个值
select COUNT(email) from Student where Email !=null |
–将null值替换为指定的字符串值
select StudentName,ISNULL(Email,'没有填写电子邮箱') from Student where ClassId=2 |
–当你看到 每一个,,各自,不同,,分别 需要考虑分组
–查询每一个班级的男生人数
–与聚合函数一起出现在查询中的列,要么也被聚合,要么被分组
select classid,Sex,COUNT(*) from Student where Sex='男' group by ClassId,sex |
–查询每一个班级的总人数,显示人数>=2的信息
–1.聚合不应出现在 WHERE 子句中–语法错误
select ClassId ,COUNT(*) as num from Student where Email is not null GROUP by ClassId having COUNT(*)>=2 order by num desc |
–完整的sql查询家庭
–5 1 2 3 4 6
–select 字段列表 from 表列表 where 数据源做筛选 group by 分组字段列表 having 分组结果集做筛选 Order by 对结果集做记录重排
select ClassId ,COUNT(*) as num from Student where Email is not null GROUP by ClassId order by ClassId desc |
–关于top的执行顺序 排序之后再取top值
select top 1 ClassId ,COUNT(*) as num from Student GROUP by ClassId order by num desc |
类型转换函数
–select :输出为结果集–虚拟表
–print:以文本形式输出 只能输出一个字符串值.
print 1+’a’
select 1,2
select * from Student
–类型转换
–Convert(目标类型,源数据,[格式]) –日期有格式
print ‘我的成绩是:’+convert(char(3),100)
print ‘今天是个大日子:’+convert(varchar(30),getdate(),120)
select getdate()
select len(getdate())
–cast(源数据 as 目标类型) 它没有格式
print ‘我的成绩是:’+cast(100 as char(3))
日期函数
--getdate():获取当前服务器日期 |
数学函数
--rand:随机数:返回0到1之间的数,理论上说可以返回0但是不能返回1 |
字符串函数
--1.CHARINDEX --IndexOf():能够返回一个字符串在源字符串的起始位置。找不到就返回0,如果可以找到就返回从1开始的索引--没有数组的概念 |
联合结果集union
--联合结果集union |
select * from Student where ClassId=2 |
–查询office这科目的全体学员的成绩,同时在最后显示它的平均分,最高分,最低分
select ' '+cast(StudentNo as CHAR(3)),cast(SubjectId as CHAR(2)),StudentResult from Result where SubjectId=1 |
–一次性插入多条数据
–1.先将数据复制到另外一个新表中,删除源数据表,再将新表的数据插入到源数据表中
–1.select */字段 into 新表 from 源表
–1.新表是系统自动生成的,不能人为创建,如果新表名称已经存在就报错
–2.新表的表结构与查询语句所获取的列一致,但是列的属性消失,只保留非空和标识列。其它全部消失,如主键,唯一键,关系,约束,默认值select * into newGrade from grade
truncate table grade
select * from newGrade
--select * into grade from newGrade
--2.insert into 目标表 select 字段列表/* from 数据源表
--1、目标表必须先存在,如果没有就报错
--2.查询的数据必须符合目标表的数据完整性
--3.查询的数据列的数量和类型必须的目标的列的数量和对象完全对应
insert into grade select classname from newGrade
delete from admin
--使用union一次性插入多条记录
--insert into 表(字段列表)
--select 值。。。。 用户自定义数据
--union
--select 值 。。。。
insert into Admin
select 'a','a'
union all
select 'a','a'
union all
select 'a','a'
union all
select 'a',null
CASE函数用法
相当于switch case—c#中的switch…case只能做等值判断
这可以对字段值或者表达式进行判断,返回一个用户自定义的值,它会生成一个新列
1.要求then后面数据的类型一致
2.第一种做等值判断的case..endcase 字段或者表达式
when .值..then .自定义值
when .值..then .自定义值
…..
else 如果不满足上面所有的when就满足这个else
end
--显示具体班级的名称
select StudentNo,StudentName,
case ClassId --如果case后面接有表达式或者字段,那么这种结构就只能做等值判断,真的相当于switch..case
when 1 then '一班'
when 2 then '2班'
when 3 then '3班'
when null then 'aa' --不能判断null值
else '搞不清白'
end,
sex
from Student
--2.做范围判断,相当于if..else,它可以做null值判断
--case --如果没有表达式或者字段就可实现范围判断
-- when 表达式 then 值 --不要求表达式对同一字段进行判断
-- when 表达式 then 值
-- .....
--else 其它情况
--end
select StudentNo,StudentName,
case
when BornDate>'2000-1-1' then '小屁孩'
when BornDate>'1990-1-1' then '小青年'
when BornDate>'1980-1-1' then '青年'
--when Sex='女' then '是女的'
when BornDate is null then '出生不详'
else '中年'
end
from Student
--百分制转换为素质教育 90 -A 80--B 70 --C 60 --D <60 E NULL--没有参加考试
select StudentNo,SubjectId,
case
when StudentResult>=90 then 'A'
when StudentResult>=80 then 'B'
when StudentResult>=70 then 'C'
when StudentResult>=60 then 'D'
when StudentResult is null then '没有参加考试'
else 'E'
end 成绩,
ExamDate
from Result
IF ELSE语法
1,.没有{},使用begin..end.如果后面只有一句,可以不使用begin..end包含
2.没有bool值,只能使用关系运算符表达式
3.也可以嵌套和多重
4.if后面的()可以省略
declare @subjectname nvarchar(50)='office' --科目名称 |
WHILE循环语法
没有{},使用begin..end
没有bool值,需要使用条件表达式
可以嵌套
也可以使用break,continue
go |
–执行循环加分
update Result set StudentResult+=2 where SubjectId=@subjectId and StudentNo in(select StudentNo from Student where ClassId=@classid) and StudentResult<=98 |
–重新计算不及格人数
set @unpassNum=(select COUNT(distinct Studentno) from Result where SubjectId=@subjectId and StudentNo in(select StudentNo from Student where ClassId=@classid) and StudentResult<60) |