💡 根据郝斌老师视频教程,整理学习笔记内容实用,完整全面;
视频 | 郝斌-SQLserver教程 |
作者 | 郝斌 |
状态 | 已学完 |
简介 | zinksl学习笔记;快速掌握查询相关的基本操作,内容完整实用 |
SQL学前导图
:::info
系统数据库:master、model、msdb、tempdb【我们自定义数据库的管理维护运行都需要系统库支持】
:::
一 、基本信息
1 相关名词
数据库相关基本概念:字段、属性、记录(元祖)、表、主键、外键
名称 | 说明 |
字段 | 记录事物某一特征 |
记录 | 同一事物多个字段的组合,表示某一事物 |
表 | 多条记录的组合,表示同类事物 |
主键 | 唯一标识某一事物的一个属性 |
外键 | 此字段:来自另一个表的主键 |
表之间多对一时:外键建在"多"表中
2 基本语句
-- 创建表案例 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 )
3 约束:主键约束、外键约束、check约束、default约束、唯一约束
定义:
对于表中某字段,操作的限制
:::info
主键约束:不允许重复的记录添加,避开了数据冗余;(主体完整性)
外键约束:通过外键约束,从语法上保证了与此关联的事物是存在的(引用完整性)
check约束:保证字段取值在合法范围内
default约束:保证字段一定有一个值
unique约束:保证数据唯一性【主键与唯一约束的区别:唯一约束可为有空】
:::
某张表中多个字段组合作主键
主键: 能够唯一标示一个事物的一个字段或者多个字段的组合,被称为主键
含有主键的表叫做主键表
主键通常都是整数 不建议使用字符串当主键(如果主键是用于集群式服务)
主键的值通常都不允许修改,除非本记录被删除
多对多表查询中,必须借助第三张表;
constraint t_pk primary key(字段1,字段2,字段3)
二、查询
查询相关: 计算列、distinct、between、in、top、null、order by 、模糊查询、聚合函数、group by、having、链接查询、嵌套查询
select 语句执行顺序
第一步:查看来自哪张表(from)
第二步:查看查询字段【如果是表中字段则输出相关字段】 如果是其他值则输出与表格对应行数的值
1 计算列
在查询语句中,可以对字段进行算术运算
select ename, sal*12 as "年薪" from emp
2 distinct(去重)
会过滤掉重复的任意值【包括null】
-- 过滤重复字段 select distinct deptno as "部门编号" from emp
3 between
限定取值范围;between需要配合where一起使用
-- between的使用 查询sal在800-1500之间的值【包含两端】 select sal from emp where sal between 800 and 1500
4 in包含
取值为in里面的值
-- 只取in内值 select sal from emp where sal in(800,1500) -- 只取in外的值 select sal from emp where sal not in(800,1500)
5 top 分页【取前几个值】
-- 取所有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
6 null
null不能参与数学运算,否则值为空
isnull()函数
isnull(a,b):如果不为空则值取a,否则取b
-- 输出前四个人年薪和基本信息 select top 4 *,sal*12 + ISNULL(comm,0) from emp
7 order by 排序
排序:order by 排序【默认升序】
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 -- 查询各部门姓名和
8 模糊查询
基本格式: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]%'
转义字符 【escape ‘\’】
在SQLserver中我们可以通过escape 定义任意符号为:转义字符
-- 搜索名字中带有%的内容 select name from student where name like '%\%%' escape '\'
三、聚合函数
单行函数和多行函数不能混合使用
count()
(1)为空(null)的记录不会被统计
-- 统计emp表中所有记录数 select count(*) from emp -- 统计emp表中所有人名 select count(ename) from emp
四、分组 group by
理解:group by a,b,c的用法先按a分组,如果a相同,再按b分组,如果b相同,再按c分组最终统计的是最小分组的信息
having对分组后的数据进行过滤
综合案例
select deptno, job,count(*) from emp where sal > 1000 group by deptno,job having count(*) > 1
五、链接查询(多表查询)
内链接:
(1)select … from A,B
(2)select … from A,B where …
(3)select … from A join B on …
(4)select … from A,B
--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)
联合的用法【union】
联合:是将两个表纵向合并
-- 联合的使用 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
联合注意事项:
①联合中的列数 需要与查询列数一致
②联合列的数据类型需要与查询数据列数据类型兼容
六 分页查询【top只有SqlServer有】
公式:
假设每页显示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
identity关键字:主键自动增长;【当被删除一个数据后:会打断主键连续自增】
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