课程地址:数据库 SQLServer 视频教程全集(99P)| 22 小时从入门到精通_哔哩哔哩_bilibili
目录
查询(最重要,难度最大)
(一)大纲
1. 计算列
2. distinct
3. between
4. in
5. top
6. null
7. order by
8. 模糊查询
9. 聚合函数
10. group by
11. having
12. 连接查询
- 定义
- 分类(内连接、外连接、完全连接、交叉连接、自连接、联合)
13. 嵌套查询(Oracle中讲)
(二)Scott 表
Scott表 是 Oracle数据库 里的例子,将它附加到 SQL Server 中
下载与导入SQL Server
SQL Server 学习之环境搭建 - 枫林雨 - 博客园
(1)下载并解压后,得到以下两个文件:
(2)设置权限(以 scott.mdf 文件为例):
对 scott.mdf 和 scott_log.ldf 两个文件都要做以上权限修改
(3)附加到 SQL Server 中
打开SSMS,数据库 - 右键 - 附加
scott表介绍
emp (EMPNO, ename, job, mgr, hiredate, sal, comm, deptno)
- 员工(员工编号,姓名,职称,上级编号,雇佣日期,工资,奖金(销售岗才有),部门编号)
dept (deptno, dname, loc)
- 部门(部门编号,部门名称,地址)
SALGRADE (GRADE, LOSAL, HISAL)
- 工资(等级,最低工资,最高工资)
计算列
select ename,* from emp -- ok,但是在Oracle中会报错,因此不建议这样写
select ename,15 from emp
查询员工表里的姓名和年薪(工资×12)
select ename, sal*12 as "年薪" from emp
-- as可以省略,"年薪" 不要写成 '年薪'(不可移植)
select 5 from emp
-- 输出的行数是emp表的行数,每行只有一个字段,值是5
select 5
-- OK,但不推荐(Oracle里报错)
注:在Oracle中字段的别名不允许用单引号括起来,但是SQL Server却允许。因此,为了兼容性,最好字段别名用双引号括起来,不要用单引号
distinct(不允许重复的)
emp中一共有14条记录,有10/20/30三种类型的deptno值
select deptno from emp -- 14行记录,不是3个
select distinct deptno from emp -- distinct deptno会过滤掉重复的deptno
select distinct comm from emp -- distinct也可以过滤掉重复的null;或者说,如果有多个null,只输出一个
select distinct comm,deptno from emp -- 整体过滤,把comm和deptno的组合进行过滤
select deptno, distinct comm from emp -- 报错,逻辑上有冲突(deptno有14条,distinct comm有5条,数目不匹配)
between(在某个范围)
查询工资在1500到3000之间(包括1500和3000)的所有的员工的信息
select * from emp
where sal>=1500 and sal<=3000 -- 写法1
select * from emp
where sal between 1500 and 3000 -- 写法2
查询工资在小于1500或大于3000之间的所有员工的信息
select * from emp
where sal<1500 or sal>3000 -- 写法1
select * from emp
where sal not between 1500 and 3000 -- 写法2
in(属于若干个孤立的值)
查询工资为1500和3000的员工信息
select * from emp where sal in (1500,3000) -- 写法1
select * from emp
where sal=1500 or sal=3000 -- 写法2
对以上查询取反,即把工资既不是1500,也不是3000的记录输出
select * from emp where sal not in (1500,3000) -- 写法1
select * from emp
where sal != 1500 and sal != 3000 -- 写法2
-- 数据库中不等于有两种表示:<> 或 != 推荐使用前者
对或取反是并且,对并且取反是或
top(最前面的若干个记录)
select top 2 * from emp -- *表示所有字段
select top 15 percent * from emp -- 14*15% = 2.1个,输出3个而不是2个(向上取整)
SQL Server 和 Oracle 里关于查询最前面若干记录的关键字是不一样的
Oracle里输出前5行数据的写法
select * from emp where rownum < 6
分页查询:每页显示几条查询记录
把工资在1500和3000之间(包括1500和3000)的员工中工资最高的前4个人的信息输出
select top 4 * from emp
where sal between 1500 and 3000 order by sal desc -- desc降序,不写则默认是升序
null(没有值,或空值)
输出奖金非空的员工的信息
select * from emp where comm is not null
null 不能参与 <> != = 运算,但可以参与 is is not 运算
0和null是不一样的,null表示空值,没有值;0表示一个确定的值
任何类型的数据都允许为null
输出每个员工的姓名、年薪(包含奖金)。假设comm是一年的奖金
select ename, sal*12+comm from emp -- 错误,因为comm里有null,跟数值相加的结果直接为null
-- 正确写法
select ename, sal*12+isnull(comm,0) from emp -- isnull(comm,0) 如果comm是null,就返回0,否则返回comm的值
null和任何数字做数学运算结果都为null,即:null不能参与任何数学运算,否则结果为空
order by(以某个字段排序)
asc是升序的意思,默认可以不写;desc是降序
select * from emp order by sal -- 默认是按照升序排序
select * from emp order by deptno,sal -- 先按deptno升序排,若deptno相同,再按sal升序排
select * from emp order by deptno desc, sal -- 先按deptno降序排序,如果deptno相同,再按照sal升序排序(注意sal是升序,不是降序)
select * from emp order by deptno, sal desc -- desc不会对deptno产生影响。先按deptno升序,若deptno相同,再按sal降序
order by a desc, b, c, d desc只对 a 产生影响,不会对后面的 b c d 产生影响
- order by a, b a和b都是升序
- order by a, b desc a升序,b降序
- order by a desc, b a降序,b升序
- order by a desc, b desc a和b都是降序
如果不指定排序的标准,则默认是升序,升序用asc表示,默认可以不写
为一个字段指定的排序标准并不会对另一个字段产生影响
强烈建议为每一个字段都指定排序的标准
模糊查询(搜索时经常使用)
对应网页的搜索框
格式
select 字段的集合 from 表名 where 某个字段的名字 like 匹配的条件
- 匹配的条件通常含有通配符
- 通配符:
- %:任意0个或多个字符
select * from emp where ename like '%A%' -- ename只要含有字母A就输出 select * from emp where ename like 'A%' -- ename只要首字母是A的就输出 select * from emp where ename like '%A' -- ename只要尾字母是A的就输出
- _:表示任意单个字符
select * from emp where ename like '_A%' -- ename只要第二个字母是A的就输出
- [a-f]:a到f中的任意单个字符,即只能是 a b c d e f 中的任意一个字符
select * from emp where ename like '_[A-F]%' -- 把ename中第二个字符是A或B或C或D或E或F的记录输出
- [a,f]:a或f
- [^a-c]:^表示取反,即不是a,也不是b,也不是c的任意单个字符
select * from emp where ename like '_[^A-F]%' -- 把ename中第二个字符不是A-F中任一个的记录输出
- %:任意0个或多个字符
注意:
- 匹配的条件必须用单引号括起来,不能省略,也不能改用双引号
双引号表示的是一个对象的名称或别名,单引号表示的是一个字符串
- 通配符作为普通字符使用的问题
create table student(
name varchar(20) null,
age int
)
insert into student values ('张三',88)
insert into student values ('Tom',66)
insert into student values ('a_b',22)
insert into student values ('c%d',44)
insert into student values ('abc_fe',56)
insert into student values ('haobin',25)
insert into student values ('HaoBin',88)
insert into student values ('c%',66)
insert into student values ('long''s',100)
select * from student
select * from student where name like '%\%%' escape '\' -- 把name中包含有%的输出
select * from student where name like '%\_%' escape '\' -- 把name中包含有_的输出
escape '\' 表示把 '\' 字符当做转义字符的标志
在sql中可以把任意的字符当做转义字符的标志,具体是把哪个字符当做转义字符,这是由escape要指定为转义字符的字符来决定的
聚合函数(多行记录返回一个值,通常用于统计分组的信息)
函数的分类
- 单行函数:每一行返回一个值,如 lower() 和 upper()
- 多行函数:多行返回一个值,如聚合函数
select lower(ename) from emp -- 最终返回的是14行
-- lower()表示小写,是单行函数(每一行都返回一个值)
-- upper表示大写
select max(sal) from emp -- 返回的是1行,max()是多行函数
聚合函数的分类
- max()
- min()
- 如 min(ename) 输出的结果,第一个字母是A(因为A是最小的)
- avg() 平均
- count() 求个数
count()
count(*) 返回表中所有记录的个数
count(字段名) 返回字段值非空的记录的个数,重复的记录也会被当做有效记录
count(distinct 字段名) 返回字段不重复并且非空的记录的个数
select count(*) from emp -- 返回emp表所有记录的个数
select count(deptno) from emp -- 返回值是14,这说明deptno重复的记录也被当做有效记录
select count(distinct deptno) from emp -- 返回值是3,统计deptno不重复的记录的个数
select count(comm) from emp -- 返回值是4,这说明comm为null的记录不会被当做有效记录
判断如下sql语句是否正确
select max(sal) "最高工资", min(sal) "最低工资", count(*) "员工人数" from emp -- OK
select max(sal), lower(ename) from emp -- 报错,单行函数和多行函数不能通用
select max(sal) from emp -- 默认把所有的信息当做一组
下次课程预告
- 分组(group by):统计部门编号、人数、平均工资
- 对分组之后的数据进行过滤(having),与where的区别(先分组后过滤要使用having)
- 连接:多张表查询
- 嵌套查询(又叫子查询,指一个select里又嵌套了另一个select):独立嵌套、相关嵌套