SqlServer教程

sql server 笔记

本文主要是介绍sql server 笔记,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

因为没书,又因为需要这个知识,所以在网上找资源看电子书,学完了就看博文再学sql知识,再巩固一下

推荐一个好地方,菜鸟工具,那里有许多教程

ps:里面的许多实例是看的视频,然后自己写的,所以没写详情的内容对数据库...2333

sql server 2005的自学笔记

还有就是命名的问题,这是最后写的,对于表的命名,可以不写as,也可以不加双引号,直接写就行了,但是名称和表之间要有空格。我下面写的有点繁琐...格式的优化可以看目录自连接后的,那都比较好点...

库有两种:系统默认的库、自己建的库

什么是数据库?

侠义:存储数据的仓库

广义:可以对数据进行存储和管理的软件以及数据本身统称为数据库

数据库是由表、关系、操作组成的。

为什么要数据库?

几乎所有的应用软件的后台都需要数据库
数据库存储的空间小,容易持久保存
一般都是mdf,ldf后缀的这两个文件(数据库移植较容易)
存储比较安全
容易维护和升级
简化对数据的操作
为将来的学习oracle准备
b/s架构包含数据库
db又叫数据库

ps:如果连接不上,可能没开启对应的sql服务,建议在附件那里找服务,然后启用sql server 服务

数据结构和数据库的区别

都是研究数据的存储与操作

数据库是在应用软件级别研究数据的存储和操作

数据结构是在系统软件级别研究数据的存储与操作

什么是连接

sql server是客户端,是访问后台的数据库,库和访问库不一样,

只有对应的数据库服务开启,才能去连接数据库,所以连接很重要

命令只能单行发送,不能一块发送

数据库是如何存储的?

字段、记录、表、属性、约束(主键、外键、唯一键、非空、check、default)、触发器

数据库是如何操作的

insert、update、delete、T-SQL、存储过程、函数、、触发器

如何显示数据

select等

为什么会有系统库?

用户创建的库需要系统来维护,最核心的是master,不能删,改,否则会影响系统数据正常

新建数据库-----数据库--右键---新建

数据库创建有两个文件,一个是数据文件,一个是日志文件,用于记录操作

删除库直接右键删除---点击关闭现有连接删除会更好,在删除不了的情况下。类似关闭相关进程

数据库如何分离和附加

不能直接复制黏贴对数据库进行拷贝

右击数据库名字---任务---分离----然后把那一行对号点完,确保数据的时效性、完整性,然后再去对应的路径下去复制ldf、mdf文件

然后附加

怎样附加?

先右键数据库,点击附加,在对应数据库的路径下找到mdf、ldf进行附加、只需要附加ldf会自动附加

对不同版本数据库进行附加出现的兼容性问题
右击数据库,点击生成脚本,然后选择版本 、

用户名的服务器角色sysadmin就是sa权限

要想下载数据库,就得先分离才能继续复制、移动
额,貌似2005没有这个功能
。。。
2008有

新的用户并且进行改密码

1.刚进去点击window身份验证登录(或者管理身份sa添加

image-20210623071932039

右键----添加用户名

image-20210623072027802

把强制密码过期去掉,这样不会报错

但是创建的用户没有权限

信息产生的重复叫冗余

表的相关数据

能够唯一标识一个事物的叫主键

关系型数据库:表示事物与事物之间的关系,也可以通过主键外键进行连接

外键:来自另外一个表的引用的索引(自己概括的)

字段:一个事物的某一个的特征

记录:字段的组合 表示的是一个具体的事物

表:记录的组合、表示的是同一类型事物的集合

表、字段、记录的关系

字段是事物的属性
记录是事物本身
表是事物的集合

一行叫做元组

列、属性:字段的另一种称谓

整体的叫做表

nvarchar是任意字符,字符长度可变化(无论是全角还是半角,每个字符都占用两个字节)

在sql中,图形化界面中,点击执行sql,会把重复的给自动去掉

image-20210623151556123

在输入相同数据后,点击再下星号,就可以避免重复而自动删掉

,但会使主键添加失败,需要对id进行更改数字来开启主键

主键、外键有点绕。。

---右键--关系---三个点点----设置主键、外键

外键来自另一个表的主键

还得确保数据类型的相同

image-20210623163753465

create table 创建表 最后的一个字段不建议写逗号,因为Oracle命令逗号执行失败

关于命令

image-20210623170114887

先创建表---再创建主键---类型要注意是nvarchar,不是nvchar,是否为空的确定,空就是null,非空就是not null

--是注释

image-20210623172441842

创建的第二个表
是emp
其实可以把constraint 名字 去掉,系统会自定义
不去掉就是自己自定义
先设置主键  primary key
然后定义属性
再设置外键   foreign key
外键要设置参考对象  references

ps:刷新建议点击添加查询的库刷新,不然出来的很慢,23333

约束是什么?

对一个表中的属性操作的限制叫做约束

分类:主键约束(不允许重复元素、避免数据的冗余)

外键约束(通过外键约束,从语法上保证了本事物所关联的其他事物一定是存在的)

事物事物之间通过外键来体现的

check约束:检查约束也就是条件约束

create table student
(
stu_id int primary key,
stu_sal int check (stu_sal>=1000 and stu_sal<=8000)
)

image-20210623174221076

意思为:插入进去在表中为student的,主键值为1,工资为。。。

default:保证事物属性有一定的值

唯一约束:unique

唯一键可以为空

保证了事物属性的取值不允许重复

但是只能有一个为空

自动增长为identity

 identity表示该字段的值会自动更新,不需要我们维护,通常情况下我们不可以直接给identity修饰的字符赋值,否则编译时会报错
 m表示的是初始值,n表示的是每次自动增加的值
如果m和n的值都没有指定,默认为(1,1)
要么同时指定m和n的值,要么m和n都不指定,不能只写其中一个值,不然会出错

create table student1
(
id int primary key identity(200,10),
name nchar(8) not null,
sex nchar(1) not null,
)
insert student1 (name,sex) values ('张三','男');

image-20210625062540302

drop table 表名 是删除表

在设置是否为空时,默认不写就是允许为空

在唯一约束下输入values,需要同时对values里加入唯一约束,不然语句错误,除非时指定的在表名后加插入属性

然后可以查看select * from 表名 看全部的输入内容

表和约束的区别:

数据库是通过表来解决事物的存储问题

数据库通过约束来解决事物取值的有效性和合法性的问题

建表的过程就是指事物属性及事物属性各种约束的过程

什么是关系:

表和表之间的联系

通过设置不同形式的外键来宝石表和表之间的关系

分类:一对一、一对多、多对多

说明分类:
假设A、B
一对一:
既可以把表A的主键充当表B的外键
也可以把表B的主键充当表A的外键
一对多:
把表A的主键充当B表的外键
或把A表的主键添加到B的表充当B表的外键
多对多:
一边的一个对另一边的多个,反过来也成立,就行
需要单独的再建一个表,来进行数据交互

多对多的一个例子:

折磨人。。

create table js
(
js_id int primary key,
js_name nvarchar(200)

)
create table bjsj
(
--只能组合是主键
bj_id int foreign key references bj(bj_id),
js_id int foreign key references js(js_id),
ke nvarchar(20),
constraint pk_bj_id_js_id primary key (bj_id,js_id,ke)
--主键约束,先定义名字,然后把bjid和jsid,ke充当主键,然后者三个都是主键,如果只设置前两个,就会出现错误在重复时。
)

关系图

字段表示的是特征
记录表示的是这个事物
表表示的是同一个事物的集合

当设置关系时,被点击的是外键,然后再对

image-20210624122214703

主键:能够唯一表示一个事物的一个字段或者多个字段的组合

含有主键的叫主键表

主键通常是整数,不建议用字符串当主键,除非是集群式服务

主键的值不允许被修改,除非本记录被删除

主键不要定义成id,而要定义成表名id或者表名_id,这是那个命名规则,方便看

要用代理主键,不要使用业务主键:

业务含义:就是有显示含义的

任何表都是不建议用业务主键

通常用在表中独立添加一个整形的编号来充当主键字段

外键:如果一个表的诺干个字段是来自另外诺干个表的主键或唯一键,则这个诺干字段就是外键

外键通常是来自另外表的主键而不是唯一键,因为唯一键可能会有null,即为空

外键不一定来自另外的表,也可能来自本表的主键

含有外键的表叫外键表,外键字段来自的那一张叫主键表

主键表和外键表的删除?

先删外键表,要删主键表,会报错,会导致外键表的数据引用失败

查询

计算列

select * from 表名
*代表所有的
from 表名  表示从表名中查询
相同的,可以把*用属性元素来表示
select bj_id,bj_name from bj;

image-20210624180349145

as可以省略,尽量使用给双引号名命名

select 数字 from 表名;
没啥用,就是看行数,我认为

oracle不允许单引号,兼容性问题,最好双引号

distinct

select distinct bj_id  from bj;

主要是不同的,通过查询语句,把不同的给显示出来(也可以过滤掉重复的null)

当有两个,就是整体上过滤。。。那两个组合相同的过滤,只有两个都重复,才会过滤

也不能
select bj_num distinct bj_id from bj;
逻辑上有冲突

between

where是对条件的抉择

select * from bj where bj_num>=20 and bj_num <=50;
select * from bj where bj_num between 20 and 50;
--查询bj表中的大20和小50的行
select * from bj where bj_num<=20 or bj_num>=50;
select * from bj where bj_num not between 20 and 50;
--是小于20或者大于50的

in

属于若干个孤立的值

select * from bj where bj_id in (1,2,3)
--在1,2,3的表中的值
select * from bj where bj_id not in (1,2,3)
--不在1,2,3的值得确定
select * from bj where bj_id<>1 and bj_id<>2 and bj_id<>3
--数据库中有两种 !=或者<>

top

select top 2 * from bj;
--输出前两个
select top 15 percent * from bj;
--取多少百分比来,如果要是多一点,就近一位
select top 4 * from bj
where bj_id between 1 and 3
order by bj_id desc;
--在前四个并且选择在包含1到3的,按照降序来,如果不写,默认是升序
--desc是降序

null

null不能参与<> != = 的运算

可以参与is is not的

select * from where bj_id is not null;

0和null不一样,null空值,零表示一个确定的值

任何数据类型都允许null

create table a1(name nvarchar(200),id int,date datetime);
insert into a1 values(null,null,null);
select * from a1;

image-20210624193612237

一个具体的值不能和一个没值的相加不能运算(null不能和任何数据运算,否则永远为空)

可以避免这个

select ename,sai*15+isnull(comm,0) from emp;
如果是null,即返回0,不然就返回comm的值

order by

select * from 表名 order by 属性;

默认升序

如果属性有两个,就是按照优先级,先按照前一个属性,再按照后一个属性

asc表示升序

desc表示降序

select * from emp order by name desc,sal;
这是先对name进行降序,然后对sal进行升序
select * from emp order by name,sal desc;
这是先对name进行升序,再对sal进行降序

如果不指定字段的排序标准,默认是asc升序

模糊查询

select * from bj where bj_num like '%0%';

image-20210624205231419

只有关键字0的

基本格式:

select 字段的集合 from 表名 where 某个字段的名字 like 匹配的条件

匹配的条件通常用含有通配符

通配符

%

A%首字母为A的
%A%有含有a的
%A伪字母含有A的

_

select * from emp where ename like '_A%';
ename只要第二个字母是A的就输出

[a-f]只能是a到f的任意单个字符

select * from emp where ename like '_[A-F]%';
把ename中的第二个字符是a到f的记录输出

[a,f]

a或者f

[^A-F]

把ename的第二个字符不是a到f的

条件必须用单引号裱起来

双引号圈起来表示字符串、别名

当有百分号时,需要用\来

查看含有%的

select * from student where name like '%/%%';
类似的用还有_等
\字符当作转义字符的标志
用m也可以
select * from student where name like '%m%%';
一般用\

聚合函数

函数分类:

单行函数、多行函数

区别:

返回的值不一样

多行:多行返回一个值

聚合函数是撮合函数

聚合函数的分类:

max()
min()
avg()平均值
count() 求个数

例子:

select lower(name) from emp;
返回小写的表中的name属性的行数,lower()是单行函数
select max(name) from emp;
返回一行
select count(*) from emo; 
返回emp表中所有记录的个数(重复的也被当作有效的记录)
可以用distinct来区分
select count(distinct gongzi) from emp;
返回是去掉重复的 
ps:当有null的时候,count只会对除了null的有效,null不会被当作记录

例子2

select max(lar) "最高工资",min(lar) "最低工资", count(*) ”共计数“ from emp;
注意,要是有select的后面语句有单行和多行,内容是不匹配的,会报错

过滤掉空的、不同的

select count(distinct comm) from emp;

group by

切换表,可以用

use 表名;
select bj_name,avg(bj_num)"平均人数"
from bj
group by bj_name;

使用group by之后select中只能出现分组后的整体信息,不能出现组内的详细信息

使用两个group by的属性,有优先级

select deptno,job,avg(sal)
from emp group by deptno,job
order by deptno;
--这是先排序对deptno,再按照deptno,再按照job分类,再进行平均工资的计算

也可以更高级

select deptno,job,avg(sal)“平均工资”,count(*)"人数",sum(sal),“总工资”
,min(sal)"最低工资"
from emp group by deptno,job
order by deptno;

把表中的记录按照不同的字段分成不同的组

group a,b,c,d
先按照啊a分组,如果a相同,再b分组....
最后统计的是最小组的信息

having

对分组之后的信息进行过滤

select deptno,job,avg(sal)  as “平均工资”
from emp group by deptno
order by deptno;
having avg(sal)>=2000
--对分组后的平均工资大于2000的进行筛选
也可以对deptno执行过滤
别名不能作为having的过滤参数

where与having

select deptno,avg(sal) "平局工资"
from emp
where ename not like '%A%' --对原始的数据过滤
group deptno  --对分组后的进行过滤
having avg(sal)>2000;
--这个是工资大于2000,且名字包含A的例子

ps:where必须写在having的前面,顺序不可颠倒

having时通常会先使用group by(必须)

如果用group by ,但是用的having,会把所有的记录当成一组来过滤

having和where不能出现别名的使用,只能用原始的字段

单行函数是每一行都返回一个结果

多行函数是多行只返回一个结果

标准输入模板

image-20210625074740311

先where再group再having再order

where不允许使用聚合函数

对于group by的使用,有两个,就是最后一个是作为其他的聚合函数的结果

into的使用

在select后和from前面,into 新表名把查询的结果放到一个表内

连接查询

将两个表或者两个以上的表以一定的连接条件连接起来,从中检索出满足条件的顺序

内连接

select ... from A,B

引用两个表叫做笛卡尔集

可以说是第一个表的所有行与第二个第一行结合,然后与第二行结合,依次....

产生结果:

行数是A,B的乘积

列数是A,B之和

select ...from A,B where ...

对产生的笛卡尔积进行过滤

select ... from A join B on ...

select "E".ename "员工名字","D".dname"部门名称"
from emp"E"
join dept "D"
on 1=1
join是连接条件
on是必须有的,不能省略,on是连接条件,即是判断
其实可以对别名不起,这件事为了方便记录
这里可以使用所谓的中文来
select”部门表”.deptno"部门编号”  
from emp "员工表"  
join dept"部门表”
on 1=1
但是通常是英文
on作为判断来筛选
select "E".ename“"员工姓名”,"D" .dname“部门名称”
from emp "E"
join dept "D"--join是连接
on "E".deptno = "D".deptno
就是在emp表中的ename和连接的dept中的dname下的数据中,把emp.deptno和dept.deptno相同的连接在一块的写出来
挡在过滤on上的一些指定内容,如
on "j".js_name='aa'
这些值的等于必须用单引号,与通配符一样

SQL92标准和SQL99标准的区别:

select ... from A,B where...    sql92

select ... from A join B on ...    sql99
结果一样,习惯用99,理解方面,自己观点

实例

工资大于4000

select emp.ename,dept.dname
from emp
join dept
on emp.deptno=dept.deptno
--因为有重复的,所以选择相等的来过滤重复的
where emp.sal>2000

工资大于2000的姓名和部门和工资等级

select * 
from emp "E"
join dept "D"
on "E".deptno="D".deptno
join salgrade "S"
on "E".sal >= "S".losal and "E".sal <= "S".hisal
where "E".sal > 2000
where  还得必须放后面,不然会语法错误
select * from emp
join dept
on emp.deptno=dept.deptno
having dept.deptno=10
这是错误的,having是针对分组后的筛选
select * from emp
join dept
on 1=1
where dept.deptno > 10;
这样是对的
也可以这样
select * from emp
join dept
on  dept.deptno > 10;
输出工资前三的员工的姓名、工资、工资等级
select top 3 ”E“.name,"E".sal,"E".grade,"D".dname
from emp "E"
join dept "D"
on emp.deptno=dept.deptno
join salgrade ”S“
on "E".sal between "S".losaland ”S“.hisal
order by ”E“.sal desc 
要是说E的名字中不包含A就是
where ”E“.ename not like '%A%'
只能在rder by前添加
找出每个部门的编号  部门的所有的员工平均工资 平均工资等级
select "T".deptno,"T".avg_sal "部门平均工资","S".grade"工资等级"
from(
select deptno,avg(sal)  "avg_sal"
from  emp
group by deptno 
 )"T"
 join salgrade "S"
 on between "T".avg_sal between "S".losal and "S".hisal
求出emp表中的所有领导的姓名
select * from
where empno in (select mgr from emp)
求出emp表中的不是领导的姓名---还得考虑是否为空
select * from
where empno isnull (select mgr from emp,0)
求平均薪资最高的部门和平均工资
select top 1 deptno"部门编号",avg(sal)"平均工资
from emp
group by deptno
order by avg(sal) desc
在使用jon时,可以使用on不用where进行
select
* 
from emp
join dept
on emp.deptno=dept.deptno and emp.sal>2000
on中写连接条件,也可以写过滤条件
等价于
select
* 
from emp
join dept
on emp.deptno=dept.deptno
where emp.sal>2000

查询的顺序

select top ...

from A

join B

on...

join c

on...

where...

group  by...

having...

order by...
--把工资大于1500的所有员工按部门分组,,把平均工资大于2000的前两个然后部门、等级
select  “T”.*,dept.dname,"S".grade
from dept
join(
select top 2 deptno,avg(sal) "avg_sal"
from emp
where sal>1500
group by deptno
having avg(sal)>2000
order by avg(sal) desc--降序,这个select是对最高的前2个进行筛选,有平均工
--资、和员工
)“T”
on  dept.deptno="T".deptno
join salgrade 
on "T".avg(sal) between salgrade.losal and salgrade.hisal

外连接

不但返回满足连接条件的记录,而且会返回部分不满足的记录

左连接

不但返回满足连接条件的记录,而且会返回左表不满足的记录

右连接

不但返回满足连接条件的记录,而且会返回右表不满足的记录

默认的join是inner,不写也中

实际意义:

返回一个事物及其该事物的相关信息,如果该事物没有相关信息,则输出null

image-20210625173056284

完全连接

join前加full的

就是把左右连接在一块了

内容包含:

两个表中匹配的所有记录

左表中那些在右表中找不到的记录,这些记录的右边全为null

右表中那些在左表中找不到的记录,这些记录的左边全为null

交叉连接

select  * 

emp from cross

join dept

等价笛卡尔集

select * from emp,dept

或者

select  * 

emp from 

join dept

on 1=1

自连接

一张表自己和自己连接起来查询

自连接是一张表的左表与右表的第一个相对,然后第二个...

用聚合函数求最高薪资
select * from emp
where sal=(select max(sal) from emp)
--因为where不能使用聚合函数,所以得用括号圈起来的语句
select * from emp"E1",emp"E2"
连续两个对一个表的记录、
有两种方法
第一种:
select * from emp"E1",emp"E2"
第二种:
select * from emp"liwai"
join emp  "liwai2"
on 1=1

不用聚合函数求薪资最高的员工信息

这个有点难,按照自己搜索学的总结一下

先创建相关表,和行

CREATE TABLE
    T_Number (
        num int
    );
 
INSERT INTO T_Number(num) VALUES(5);
INSERT INTO T_Number(num) VALUES(23);
INSERT INTO T_Number(num) VALUES(-6);
INSERT INTO T_Number(num) VALUES(7);

如果想得到23最大,就是得到没有比23还大的数,我们可以先得到比23少的数

select lesser.num,greater.num
from t_number lesser,t_number greater
where lesser.num<greater.num

image-20210625193027491

这样就会得到左面第一行的所有比23小的

然后对左表进行筛选

select num 
from t_number
where num not in
(
select lesser.num
from t_number lesser,t_number greater
where lesser.num<greater.num
)

这样也对,但是如果有两个23,就会出现差错,所以要用distinct来进行过滤

select distinct num 
from t_number
where num not in
(
select lesser.num
from t_number lesser,t_number greater
where lesser.num<greater.num
)

image-20210625193429954

233333

联合

image-20210625194921357

mgr表示上司

empno表示下属

这个表只是一部分

然后

只需要对上司的等于下属的标号就行,因为这样会把有上司和员工的给筛选出来

select e1.ename,e1.sal,e2.ename"上司的名字"
from emp e1
join emp e2
on e1.mgr=e2.empno--对有关系的进行选择
如果要是在mgr上有null
union
ename,sal,'最大老板'
from emp  where mgr is null;
--可以看到把null变了

表和表之间的数据以纵向的方式连接在一起叫联合

联合的注意:

若干个select 子句输出的列数必须是相等的

而且

必须得是兼容的,与上一个select的

小结

主键必须有值,不能为空,可以用identity进行起始值的,或者自己设置

当进行了identity的设置,可以不用对其进行赋值,当某个记录删除时,还会按照删除的那个继续递增

删除一个表的行

delete from 表名 where 属性=xxxx

视图

简化查询

避免了代码的冗余,属性大量重复sql的语句

什么是视图?

从代码上看是一个select语句

试图逻辑上被当作一个虚拟表看待

视图格式

create view 视图的名字

as

select 的语句
--select前面不能加begin、后后能加end

视图的优点

增加数据的保密性

简化查询

视图的缺点

增加了数据库维护的成本

视图只是简化查询,不能加快查询

视图不是物理表、是虚拟表

不建议通过视图更新视图所依附的原始表的数据或结果

视图命名一般以v开头,v_xxx_xxxxxx

视图的select语句必须的为所指定的列取别名

事务

事物一系列操作要么成功、要么失败

事务主要保证数据的合理性和并发处理的能力

通俗说:

事务可以保证避免数据处于一种不合理的状态

利用事务可以实现多个用户对资源共享的同时访问

事务必须的保证多个用户对资源共享同时访问,数据库给用户的反应是合理的

事务和线程的关系

事务也是通过锁来解决很多问题

线程同步就是通过锁来解决的

脏读”可重复读

幻读“通过设置事务的优先级可避免

第三方插件要想完成预期功能,一般必须借助数据库的事务机制

事务的三种运行模式:

自动提交事务:

每条单独的语句都是一个事务。如果成功执行,则自动提交;如果错误,则自动回滚.

显式事务:

每个事务均以BEGIN TRANSACTION语句显式开始,以COMMIT或ROLLBACK语句显式结束。

隐性事务:

在前一个事务完成时新事务隐式启动,但每个事务仍以COMMOIT或ROLLBACK语句

事务的四个属性:原子性、一致性、隔离性、持久性

原子性:事务是一个完整的操作。事务的各步操作是不可分的(原子的)﹔要么都执行,要么都不执行。
一致性:当事务完成时,数据必须处于一致状态,要么处于开始状态要么处于结束状态不允许出现中间状态。
隔离性:指当前的事务与其他未完成的事务是隔离的。在不同的隔离级别下,事务的读取操作,可以得到的结果是不同的。
持久性:事务完成后,它对数据库的修改被永久保持,事务日志能够保持事务的永久性。

分页查询

image-20210626063406118emp表

最高的前三个工资的所有信息

select top 3 *
from emp
order by sal desc;

工资从高到低,输出是前3到6个的

select top 3 *
from emp
where empno not in 
(select top 3 empno order by sal desc)
order by sal desc;

工资从高到低,输出是前7到9个的

select top 3 *
from emp
where empno not in 
(select top 6 empno order by sal desc)
order by sal desc;

一些小知识的自我总结:

业务主键和逻辑主键

业务主键是使用有业务意义的字段做主键,比如身份证号,银行账号等;

逻辑主键是使用没有任何业务意义的字段做主键。因为很难保证业务主键不会重复(身份证号重复)、不会变化(账号升位),因此推荐使用逻辑主键。

主键有两种定义方式:

1.
...
id int primary key not null,
...
2.
...
id int not null,
primary key (id)
...

关于nvarchar、nchar、char的

在看nvarchar和char的时候,发现还是用nvarchar比较好,在业务不算太大,对数据的要求不太多,nvarchar可以根据实际长度来存储数据长度,但是检索数据慢,同比char,在设置几个就是几个,不足的用空格代替,但这样会对内存的存储造成一定压力。

char是英文一个字节、汉字两个字节

ncarchar英文汉字都是两个字节

varchar是和nvarchar一样效率,但字符的占有跟char一样

nchar占用空间比char大。比如char格式下一个字母只占用一个字节,汉字占用两个,nchar所有字符都占用两个字节。

修改表结构

添加表

alter table 表名 add 属性 数据类型 是否为空;

删除表的某一属性

alter table 表名 drop 属性

数据操纵语言

除了int的insert插入不带单引号,其他的都带

INSERT INTO T_Person(Id,Name,Age) VALUES(1,'Jim',20);

更新语句

update T_Person set age=age+1 where name='tom' or age<25

删除表

delete from 表名
删除指定记录
insert into T_Person values(1,'陈优秀',24)
select * from T_Person;
delete from T_Person where age >20;

WHERE 中可以使用的逻辑运算符:or、and、not、<、>、=、>=、<=、!=、<>等.

还有一种模糊查询

select * from T_Employee where fname like '_arry';
--这是查前面一个的字符
select * from T_Employee where fname like '%n%';
--这是查询含有n的模糊匹配

in包含于

select * from T_Employee where fage in(21,23,25)
--在表中的21,23,25的出来
--下面的两个等价
...
where fage >= 23 and fage <=30
where fage between 23 and 30

聚合函数是对分组操作结果进行运算

sql server函数

abs()求绝对值

ceiling()最大上限

floor()最大下限

round()四舍五入

LEN():求字符串长度。LEN('abc')=3
LOWER()、UPPER():转小写、大写

LTRIM():去掉字符串左侧空格
RTRIM():去掉字符串右侧空格

GETDATE():取当前日期时间
DATEADD(datepart,number,date):计算增加以后的日期。参数 date 为待计算的日期,参数 datepart 为计量单位(YEAR,YY,MONTH,MM,DAY,DD 等)DATEADD(DAY,3,date)为计算日期 date 的 3 天后的日期,DATEADD(MONTH,-8,date)为计算日期 date 的 8 个月前的日期
DATEDIFF(datepart,startdate,enddate):计算两个日期之间的差额。datepart 为计量单位
DATEPART(datepart,date):返回一个日期的特定的部分

--查询员工入职年数.SELECT FName,FInDate,DATEDIFF(YEAR,FInDate,GETDATE())FROM T_Employee;
查询各入职年数的员工个数.
SELECT DATEDIFF(YEAR,FInDate,GETDATE()),COUNT(*) 
FROM T_Employee
GROUP BY DATEDIFF(YEAR,FInDate,GETDATE());

空值处理

select isnull(fname,'佚名') 姓名 from empolyee

流控制函数

CASE expression
WHEN value1 THEN return_value1
WHEN value2 THEN return_value2
WHEN value3 THEN return_value3
ELSE default_return_value
END

在网上看一个例子,很实用

--有一张表T_Scroes,记录比赛成绩:
--Date    Name  Scroe
--2008-8-8  拜仁  胜
--2008-8-9  奇才  胜
--2008-8-8  湖人  胜
--2008-8-10 拜仁  负
--2008-8-8  拜仁  负
--2008-8-12 奇才  胜

--要求输出下面格式:
--Name 胜 负
--拜仁 1  2
--湖人 1  0
--奇才 2  0

-注意:在中文字符串前加 N,比如 N'胜'

emmmm

select name,

sum

(case score

when n'胜' then 1

else 0

end

)as 胜,

sum

(

case score

when n'负' then 1

else 0

end

)as 负

from t_score

group by  name;

还有datetime也是一个数据类型,他的格式是xxxx-xx-xx xx:xx 也需要加引号说明的

这篇关于sql server 笔记的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!