知识点、SQL语句学习及详细总结

sql server详细的基础总结,可先点开CSDN自带的博客目录看看大体结构~

一. 数据库简介和创建

1. 系统数据库

在安装好SQL SERVER后,系统会自动安装5个用于维护系统正常运行的系统数据库:
(1)master:记录了SQL SERVER实例的所有系统级消息,包括实例范围的元数据(如登录帐号)、端点、链接服务器和系统配置设置。
(2)msdb:供SQL SERVER 代理服务调度报警和作业以及记录操作员的使用,保存关于调度报警、作业、操作员等信息。(备份还原时)
(3)model:SQL SERVER 实例上创建的所有数据库的模板。
(4)tempdb:临时数据库,用于保存临时对象或中间结果集,为数据库的排列等操作提供一个临时工作空间。(每次启动都会重新创建)
(5)Resource:一个只读数据库,包含了SQL SERVER 的所有系统对象。(隐藏的数据库)

2. 数据库的组成

2.1 数据文件
(1)主要数据文件:扩展名为 .mdf ,每个数据库有且只能有一个。
(2)次要数据文件:扩展名为 .ndf , 可以没有或有多个。

2.2 日志文件
扩展名为 .ldf ,用于存放恢复数据库的所有日志信息。

2.3 数据的存储分配
(1)数据文件和日志文件的默认存放位置为:\Programe Files\Microsoft SQL Server\MSSQL.1\MSSQL\Data文件夹。
(2)数据的存储分配单位是数据页。一页表是一块8KB的连续磁盘空间。
(3)页是存储数据的最小空间分配单位,页的大小决定了数据库表中一行数据的最大大小。

3. SQL语句 数据库操作

(1)创建数据库

CREATE DATABASE database_name

二. SQL基础

SQL(Structured Query Language,结构化查询语言)是用户操作关系数据库的通用语言。

1. SQL功能概述

这里写图片描述

2. 系统提供的数据类型

2.1 数值数据类型

数据类型

说明

存储空间

bit

bit数据类型是整型,其值只能是0、1或空值。这种数据类型用于存储只有两种可能值的数据,如Yes 或No、True 或False 、On 或Off. (很省空间的一种数据类型,如果能够满足需求应该尽量多用。)

1字节

tinyint

tinyint 数据类型能存储从0到255 之间的整数。它在你只打算存储有限数目的数值时很有用。

1字节

smallint

smallint 数据类型可以存储从- 2的15次幂(-32768)到2的15次幂(32767)之间的整数。这种数据类型对存储一些常限定在特定范围内的数值型数据非常有用。(如果tinyint类型太单调不能满足您的需求,您可以考虑用smallint类型,因为这个类型相对也是比较安全的,不接受恶意脚本内容的嵌入。)

2字节

int

int 数据类型可以存储从- 2的31次幂(-2147483648)到2的31次幂 (2147483 647)之间的整数。存储到数据库的几乎所有数值型的数据都可以用这种数据类型

4个字节

numeric(p,s) 或 decimal(p,s)

数据类型能用来存储从-10的38次幂-1到10的38次幂-1的固定精度和范围的数值型数据。使用这种数据类型时,必须指定范围和精度。 范围是小数点左右所能存储的数字的总位数。精度是小数点右边存储的数字的位数

最多17个字节

2.2 普通编码字符串类型

数据类型

说明

存储空间

char(n)

char数据类型用来存储指定长度的定长非统一编码型的数据,n表示字符串的最大长度,取值范围为1~8000 (若实际字符串控件小于n,系统自动在后面补空格)

n字节_________

varchar(n)

可变长度的字符串类型,n表示字符串的最大长度,取值范围为1~8000。

字符数+2字节额外开销

text

text 数据类型用来存储大量的非统一编码型字符数据。这种数据类型最多可以有231-1或20亿个字符.

每个字符一个字节

char 和 varchar的区别:
若某列数据类型为varchar(20),存字符串”Jone”时,只占用4个字节,而char(20)会在为填满的空间中填写空格。所以, varchar类型比char类型更节省空间,但它的开销会大一些,处理速度也慢一些。因此,n值比较小(小于4),用char类型更好些。

2.3 统一编码字符串类型(Unicode)

数据类型

说明

存储空间

nchar(n)

nchar 数据类型用来存储定长统一编码字符型数据。统一编码用双字节结构来存储每个字符,而不是用单字节(普通文本中的情况)。它允许大量的扩展字符。此数据类型能存储4000种字符,使用的字节空间上增加了一倍.

2n字节_________

nvarchar(n)

nvarchar 数据类型用作变长的统一编码字符型数据。此数据类型能存储4000种字符,使用的字节空间增加了一倍.

字符数+2字节额外开销

ntext

最多可存储2的30次方-1将近10亿个字符

每个字符两个字节

三. SQL数据操作语言

1.数据查询语句

1.1 查询语句的基本结构

SELECT子句用于指定输出的字段;
FROM子句用于指定数据的来源;
WHERE子句用于指定数据的选择条件;
GROUP BY子句用于对检索到的记录进行分组;
HAVING 子句用于指定组的选择条件;
ORDER BY 子句用于对查询的结果进行排序;
以上子句中,SELECT 子句和FROM子句是必需的,其它是可选的。

1.2 单表查询

1.2.1选择表中若干列

(1)查询指定的列

例子 :SELECT Sname,Sno FROM Student

(2)查询全部列

例子 :SELECT * FROM Student

(3)查询经过计算的列

例子 :SELECT Sname,year(getdata()) - year(Birthdate) FROM Student

1.2.2 选择表中的若干元祖

(1)消除取值相同的行:DISTINCT

例子 :SELECT DISTINCT Sno FROM Student

(2)查询满足条件的元祖

查询条件

谓 词

比较

=、>、>=、<=、<、<>、!=、!>、!<

确定范围

BETWEEN…AND、 NOT BETWEEN…AND

确定集合

IN 、NOT IN

字符匹配

LIKE 、NOT LIKE

空值

IS NULL、IS NOT NULL

多重条件(逻辑谓词)

AND、OR

a.比较大小
例子 :SELECT Sname FROM Student WHERE year(getdata()) - year(Birthdate) < 20

b.确定范围
BETWEEN…AND 和 NOT BETWEEN…AND可用于查找属性值在或不在指定范围。

BETWEEN…AND 代表的范围是上限值和下限值之间(包括边界值),即为 true。
NOT BETWEEN…AND 代表的范围是不在上限值和下限值之间(不包括边界值),即为true。(若判断值为边界值时,为 false)

例子 :SELECT Sno,Cno FROM SC WHERE Grade BETWEEN 80 AND 90
此查询等价于:SELECT Sno,Cno FROM SC WHERE Grade >= 80 AND Grade <= 90

例子 :SELECT Sno,Cno FROM SC WHERE Grade NOT BETWEEN 80 AND 90
此查询等价于:SELECT Sno,Cno FROM SC WHERE Grade < 80 OR Grade > 90

c. 确定集合
IN运算符的含义:当列中的值和集合中的某个常量值相等时,结果为True
NOT IN运算符的含义:当列中的值和集合中的全部常量值都不相等时,结果为True

例子 :SELECT Sno FROM Student WHERE Dept IN ('信息管理系','计算机系')
此查询等价于:SELECT Sno FROM Student WHERE Dept = '信息管理系' OR Dept = '计算机系')

例子 :SELECT Sno FROM Student WHERE Dept NOT IN ('信息管理系','计算机系')
此查询等价于:SELECT Sno FROM Student WHERE Dept != '信息管理系' AND Dept != '计算机系')

d. 字符串匹配
Like运算符用于查找指定列中与匹配串匹配的元祖。

通配符

含义

_(下划线)

匹配任意一个字符

%(百分号)

匹配0个或多个字符

[]

匹配[]中的任意一个字符。如[abcd]表示匹配abcd其中任何一个,若是连续的,可以用 - 表示,如[a-d]

[^]

不匹配[]中的任意一个字符。如[^abcd]表示不匹配abcd其中任何一个,若是连续的,可以用 - 表示,如[^a-d]

例子 :

e. 涉及空值的查询
空值(NULL)在数据库中有特殊含义,表示当前不确定或未知的值。判断是否为NULL时,不可用普通的比较运算符,需用IS NULL
例子 :SELECT Sno FROM Student WHERE Grade IS NULL

1.2.3 对查询结果进行排序

将查询结果按照指定的顺序显示。ASC表示按列值升序排列(从上往下,值从大到小)。DESC表示按列值降序排列(从上往下,值从小到大)。默认为ASC

例子 :SELECT Sno,Grade FROM SC ORDER BY Grade DESC

1.2.4 使用聚合函数统计数据

聚合函数也称为统计函数或集合函数,作用是对一组值进行计算并返回一个统计结果。

聚合函数

含义

COUNT(*)

统计表中元祖的个数

COUNT([DISTINCT]<列名>)

统计本列的非空列值个数

SUM(<列名>)

计算列值的和值(必须是数值型列)

AVG(<列名>)

计算列值的平均值(必须是数值型列)

MAX(<列名>)

计算列值的最大值

MIN(<列名>)

计算列值的最小值

上述函数除 COUNT(*) 外,其它函数在计算过程中均忽略NULL值

聚合函数不能出现在WHERE子句中!

1.2.5 对数据进行分组统计

需要先对数据进行分组,然后再对每个组进行统计。分组子句GROUP BY。在一个查询语句中,可以用多个列进行分组。
分组子句跟在WHERE子句的后面:

(1)使用GROUP BY 子句

(2)使用HAVING 子句
HAVING子句用于对分组后的统计结果再进行筛选,它的功能与WHERE子句类似,它用于组而不是单个记录。在HAVING子句中可以使用聚合函数,但在WHERE子句中不能,通常与GROUP子句一起使用。

(3)WHERE 、GROUP BY 、HAVING 的作用及执行顺序

可以分组操作之前应用的筛选条件,在WHERE子句中指定它们更有效,这样可以减少参与分组的数据行。在HAVING子句中指定的筛选条件应该是那些必须在执行分组操作之后应用的筛选条件。

以上例子比较:第一种是按照系分组好了之后,只采取所有系中的两个系,显然效率不高。而第二种是先进行WHERE筛选条件之后,再进行GROUP BY 计算,显示更好。

1.3 多表连接查询

若一个查询同时涉及到两张或以上的表,则称为连接查询。

1.3.1 内连接

使用内连接时,如果两个表的相关字段满足条件,则从两个表中提取数据组成新的记录。

注意:连接条件中的连接字段必须是可比的,必须是语义相同的列。

1.3.2 自连接

自连接是一种特殊的内连接,相互连接的表在物理上是一张表,但在逻辑上可以看做是两张表。

通过为表取别名的方法,可以让物理上的一张表在逻辑上成为两张表。(一定要为表取别名!)

1.3.3 外连接

内连接操作中,只有满足条件的元祖才能出现在查询结果集中。
外连接是只限制一张表中的数据必须满足条件,而另一张表的数据可以不满足条件。

LEFT [OUTER] JOIN 称为左外连接,含义是限制表2中的数据必须满足条件,但不管表1中的数据是否满足条件,均输出表1中的数据。
LEFT [OUTER] JOIN 称为右外连接,含义是限制表1中的数据必须满足条件,但不管表2中的数据是否满足条件,均输出表2中的数据。

内连接与外连接的区别:
这里写图片描述

内连接:表A与表B进行内连接,则结果为两个表中满足条件的记录集,即C部分。
外连接:如果表A和表B进行左外连接,则结果为 记录集A + 记录集C;如果表A和表B进行右外连接,则结果为 记录集B + 记录集C。

例子解析:如果存在部分课程为被人选择,则必定在Course表中有但在SC表中没有出现,即在进行外连接时没人选的课程在与SC表构成的连接结果集中,对应的Sno、Cno、Grade列必定为空,所以只需在连接后的结果中选出SC表中Sno或Cno为空的元祖即可。

例子解析: 上述例子要求统计每个学生的….,所以在GROUP BY分组时,是按照学生表中的学号来分。而对于聚合函数COUNT,上述要求统计每个学生的选课门数,若写成COUNT(S.Sno)或COUNT(*),则对没选课的学生都返回1,因为在外连接结果中,S.Sno不会是NULL,而COUNT(*)函数本身也不考虑NULL,它是直接对元祖个数进行计数。

注意:在对外连接的结果进行分组、统计等操作时,一定要注意分组依据列和统计列的选择。

1.4 使用TOP限制结果集行数

在使用SELECT语句进行查询时,有时只需要前几行数据。

TOP谓词写在SELECT单词的后面(如果有DISTINCT,则在DISTINCT后面)。

2.数据更改功能

2.1 插入数据

(1)简单插入语句

(2)多行插入语句

(3)不按表顺序插入语句
按与表列顺序不同的顺序插入数据

2.2 更新数据

(1)无条件更新

(2)有条件更新

2.3 删除数据

(1)无条件删除

(2)有条件删除

四. 高级查询

1. CASE函数

CASE函数是一种多分支函数,它可以根据条件列表的值返回多个可能的结果表达式中的一个。

1.1 简单CASE函数

1.2 搜索CASE函数

简单 CASE函数只能将input_expression与一个单值进行比较,如果需要跟一个范围内的值进行比较,就需要搜索CASE函数

2. 子查询

如果一个SELECT语句嵌套在另一个SELECT、INSERT、UPDATE或DELETE语句中,则称为子查询或内层查询;而包含子查询的语句称为主查询。

子查询通常用于满足下列需求之一:

子查询通常有几种形式:

2.1 使用基于集合测试的嵌套子查询

使用嵌套子查询进行基于集合的测试时,子查询返回的是一个值列表,外层查询通过运算符 IN 或 NOT IN,对子查询返回的结果集进行比较。

包含这种子查询形式的查询语句是分步骤实现的,即先执行子查询,然后在子查询的结果基础上执行外层查询(先内后外)。子查询返回的结果是一个集合,外层查询就是在这个集合上使用IN运算符进行比较。

上述的例子可以看出子查询连接查询可以互通,但在某些情况下是不可以的:

这个查询不能完全用连接查询 实现,因为这个查询的语义是要先找出选了JAVA课程的学生,然后再计算这些学生的选课门数和平均成绩。

连接查询:

以上查询是错误的,查出来学生的选课门数都是1 !!! 实际上这个1指的是JAVA这一门课程,,其平均成绩也是JAVA成绩。

【注意:】连接查询和子查询的区别:★★★★★

执行完WHERE子句之后,连接的大表中的数据就只剩下JAVA这一门课程的情况了,显然不符情况。

【注意:】在子查询中否定和在外查询中否定的区别 ★★★★★

IN 和 != 的搭配 相较于 NOT IN 和 =的搭配是否相同?
在子查询中否定和在外查询中否定的区别?

这个例子,连接查询是错误的,嵌套子查询中方法一在子查询中的否定是错误的!嵌套子查询中方法二在外查询中的否定是正确的!

【连接查询】:
- 上面已经讲过,对于连接查询,所有的条件都是在连接之后的结果表上进行的,而且是逐行进行判断。一旦发现满足要求“Cno != ‘C001’”,则此行满足条件。所以最后的结果既包括没有选C001课程的学生,也包含选了C001同时选了别的课程的学生。

【含有嵌套的子查询】:
- 对于含有嵌套的子查询的查询,是先执行子查询,然后在子查询的结果基础上再执行外层查询。而且在子查询中也是逐行判断的,当发现有满足条件的数据时,将此行数据作为外行查询的一个比较条件。

本例要查询的是某个学生所选的全部课程中均不包含C001课程,如果将否定放在子查询中,则查出的学生既包括没有选C001课程的学生,也包含选了C001同时选了别的课程的学生。显然,这个否定的范围不够。

通常情况下,对于这种带有部分否定条件的查询都应该用子查询来实现,而且应该放在外层!

2.2 使用比较测试的嵌套子查询

使用嵌套子查询进行比较测试时,要求子查询只能返回单个值。外层查询一般通过比较运算符(=、<>、 <= 、>=),将外层查询中某个列的值与子查询返回的值进行比较。

2.2 使用SOME 和 ALL 嵌套子查询

当子查询返回单值时,可以使用比较运算符进行比较,但返回多值时,就需要通过SOME和ALL修饰,同时必须使用比较操作符!

该语句实际上等价于:查询比第一学期学分最高的课程的学分小的其它学期的课程名、开课学期和学分:

该语句实际上是查询成绩大于或等于90的学生的学号及选修的全部课程的课程号和考试成绩
,可用子查询来做:

未完待续……

希望对你们有帮助 :)