根据郝斌老师视频教程,整理学习笔记内容实用,完整全面;
视频 | 郝斌-SQLserver教程 |
---|---|
作者 | 郝斌 |
状态 | 已学完 |
简介 | zinksl学习笔记;快速掌握查询相关的基本操作,内容完整实用 |
:::info
系统数据库:master、model、msdb、tempdb【我们自定义数据库的管理维护运行都需要系统库支持】
:::
名称 | 说明 |
---|---|
字段 | 记录事物某一特征 |
记录 | 同一事物多个字段的组合,表示某一事物 |
表 | 多条记录的组合,表示同类事物 |
主键 | 唯一标识某一事物的一个属性 |
外键 | 此字段:来自另一个表的主键 |
表之间多对一时:外键建在"多"表中
-- 创建表案例
create table table1
(
-- |字段|类型|约束 |约束名 |主键
t_id int constraint t_pk primary key,
t_name varchar(20) not null,
t_age int not null,
t_sex varchar(1)
)
create table table2
(
t2_id int constraint t2_pk primary key,
t2_name varchar(15) not null,
-- |字段|类型 |约束 |约束名 |外键 |涉及到 |表名
t1_id int constraint t2_fk foreign key references table1
)
定义:
对于表中某字段,操作的限制
:::info
含有主键的表叫做主键表
主键通常都是整数 不建议使用字符串当主键(如果主键是用于集群式服务)
主键的值通常都不允许修改,除非本记录被删除
多对多表查询中,必须借助第三张表;
constraint t_pk primary key(字段1,字段2,字段3)
查询相关: 计算列、distinct、between、in、top、null、order by 、模糊查询、聚合函数、group by、having、链接查询、嵌套查询
select 语句执行顺序
第一步:查看来自哪张表(from)
第二步:查看查询字段【如果是表中字段则输出相关字段】 如果是其他值则输出与表格对应行数的值
在查询语句中,可以对字段进行算术运算
select ename, sal*12 as "年薪" from emp
会过滤掉重复的任意值【包括null】
-- 过滤重复字段
select distinct deptno as "部门编号" from emp
限定取值范围;between需要配合where一起使用
-- between的使用 查询sal在800-1500之间的值【包含两端】
select sal from emp
where sal between 800 and 1500
取值为in里面的值
-- 只取in内值
select sal from emp
where sal in(800,1500)
-- 只取in外的值
select sal from emp
where sal not in(800,1500)
-- 取所有sal中的前两个值
select top 2 sal from emp
案例
-- 输出工资在1500-3000之间工资最高的前四个人姓名工资
select top 4 ename,sal from emp
where sal between 1500 and 3000
order by sal desc
null不能参与数学运算,否则值为空
isnull(a,b):如果不为空则值取a,否则取b
-- 输出前四个人年薪和基本信息
select top 4 *,sal*12 + ISNULL(comm,0) from emp
asc:升序
desc:降序
① order by A,B
先按照A升序排序,再将A相同的B升序排序
② order by A desc, B
A降序排序,再将A相同的B升序排序
③ order by A desc, B,C,D
对A降序排序,不会对BCD产生影响
④ order by A,B desc
先按A升序,再按A相同的B降序
-- 查询姓名和工资,以工资降序排列
select ename,sal from emp
order by sal desc
-- 查询各部门姓名和
基本格式:select 字段名 from 表名 where 字段名 like 匹配条件
单引号和双引号的区别:单引号表示字符串,双引号表示标识符(变量 函数等的名字)
匹配条件:需要用单引号‘’括起来
% :任意一个或多个字符
_ : 任意单个字符
[a-f]: 匹配从a-f任意单个包含a和f
[a,f]:匹配a和f任意单个
[^a-f]:匹配不是a-f的其他任意单个字符
-- 在员工表中查询所有名字以A开头的人名
select ename from emp where ename like 'A%'
-- 在员工表中查询所有名字以A-F开头的人名
select ename from emp where ename like '[A-F]%'
-- 在员工表中查询所有名字以A或F开头的人名
select ename from emp where ename like '[A,F]%'
-- 在员工表中查询所有名字不以A-F开头的人名
select ename from emp where ename like '[^A-F]%'
在SQLserver中我们可以通过escape 定义任意符号为:转义字符
-- 搜索名字中带有%的内容
select name from student where name like '%\%%' escape '\'
单行函数和多行函数不能混合使用
(1)为空(null)的记录不会被统计
-- 统计emp表中所有记录数
select count(*) from emp
-- 统计emp表中所有人名
select count(ename) from emp
理解:group by a,b,c的用法先按a分组,如果a相同,再按b分组,如果b相同,再按c分组最终统计的是最小分组的信息
综合案例
select deptno, job,count(*) from emp
where sal > 1000
group by deptno,job
having count(*) > 1
--1.求出每个员工的姓名 部门编号 薪水 和 薪水的等级
select S.grade
from emp "E"
join salgrade "S"
on E.sal<=S.hisal and E.sal>=S.losal
--2.查找每个部门的编号 该部门所有员工的平均工资 平均工资的等级
select T.dno,S.grade,T.avg_sal
from(select D.deptno as "dno",AVG(sal) as "avg_sal"
from emp "E" join dept "D" on E.deptno = D.deptno
group by D.deptno) "T" join salgrade "S" on T.avg_sal >= S.losal and T.avg_sal<= S.hisal
--3.求出emp表中所有领导的姓名
select ename from emp
where empno in(select mgr from emp)
--4.求出平均薪水最高的部门的编号和部门的平均工资
select T.deptno,D.dname,T.avg_sal from
(select deptno,AVG(sal) as "avg_sal"
from emp group by deptno) "T" join dept "D" on T.deptno = D.deptno
--5.把工资大于所有员工平均工资最低的前3个人的姓名 工资 部门编号输出
select top 3 E.ename,E.sal,E.deptno,D.dname
from emp "E" join dept "D" on E.deptno = D.deptno
where E.sal > (select AVG(sal) from emp )
order by sal asc
定义:不但返回满足连接条件的所有记录,而且会返回部分不满足条件的记录
(1)左外链接
- 用左表的第一行分别和右表的所有行进行联接,如果有匹配的行,则一起输出,如果右表有多行匹配,则结果集输出多行,如果没有匹配行,则结果集中只输出一行,该输出行左边为左表第一行内容,右边全部输出null
- 然后再用左表第二行和右边所有行进行联接,如果有匹配的行,则一起输出,如果右表有多行匹配,则结果集输出多行,如果没有匹配行,则结果集中只输出一行,该输出行左边为左表第二行内容,右边全部输出null
- 以此类推,直至左边所有行连接完毕
- 因为右边很可能出现有多行和左边的某一行匹配,所以左联接产生的结果集的行数很可能大于leftjoin 左边表的记录的总数
- 左向外联接的结果集包括LEFTOUTER子中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行则在相关联的结果集行中右表的所有选择列表列均为空值。
实际意义:返回一个事物及其该事物的相关信息,如果该事物没有相关信息,则输出null
(2)右外链接
与左链接相同
--在不使用聚合函数的情况下,查询工资最高的人员信息
select * from emp "E"
where E.sal not in (select E1.sal from emp "E1" join emp "E2" on E1.sal < E2.sal)
联合:是将两个表纵向合并
-- 联合的使用
select emp.ename,emp.sal,E.ename "上级名称"
from emp join emp "E"
on emp.mgr = E.empno
union select ename ,sal,'boss'
from emp where mgr is null
联合注意事项:
假设每页显示n条记录,当前要显示的是第m页表名是A 主键是A_id
**select top n ***
from A
*where A_id not in (select top (m-1)n A_id from A)
案例:
-- 分页查询每页显示4人信息(按照工资降序)
--1-3
select top 3 * from emp
order by sal desc
-- 4-6
select top 3 * from emp
where empno not in(select top 3 empno from emp
order by sal desc)
order by sal desc
-- 7-9
select top 3 * from emp
where empno not in(select top 6 empno from emp
order by sal desc)
order by sal desc
-- 10-12
select top 3 * from emp
where empno not in(select top 9 empno from emp
order by sal desc)
order by sal desc
-- 13-14
select top 3 * from emp
where empno not in(select top 12 empno from emp
order by sal desc)
order by sal desc
create table tableT
(
empid int identity(1, 1),
ename nvarchar(20) not null
)
-- 插入数据
insert into tableT values ('aaaa');
insert into tableT values ('bbbb');
insert into tableT values ('cccc');
insert into tableT values ('dddd');
--删除empid为4的记录select* from emp
delete from tableT delete from emp where empid =4
--因为执行delet时empid为4,所以下一句插入时empid会从5开始
insert into tableT values('eeee')
delete from tableT where empid = 5
dbcc checkident('tableT',reseed,3) --此行把emp表中identity字段的初始值重新设置为3
insert into tableT values('eeee') --此时插入记录时,empid为4,上一行已经把empid设置成了3
select* from emp
视图可以作为一个临时表处理:可以简化查询
-- 视图操作
--创建vs1视图
CREATE VIEW vs1
AS SELECT ename,deptno FROM emp
-- 使用视图vs1查数据
select sal from vs1