SQL SERVER 基础篇(一):知识点、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 数值数据类型

数据类型说明存储空间
bitbit数据类型是整型,其值只能是0、1或空值。这种数据类型用于存储只有两种可能值的数据,如Yes 或No、True 或False 、On 或Off. (很省空间的一种数据类型,如果能够满足需求应该尽量多用。)1字节
tinyinttinyint 数据类型能存储从0到255 之间的整数。它在你只打算存储有限数目的数值时很有用。1字节
smallintsmallint 数据类型可以存储从- 2的15次幂(-32768)到2的15次幂(32767)之间的整数。这种数据类型对存储一些常限定在特定范围内的数值型数据非常有用。(如果tinyint类型太单调不能满足您的需求,您可以考虑用smallint类型,因为这个类型相对也是比较安全的,不接受恶意脚本内容的嵌入。)2字节
intint 数据类型可以存储从- 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字节额外开销
texttext 数据类型用来存储大量的非统一编码型字符数据。这种数据类型最多可以有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子句用于指定数据的来源;
WHERE子句用于指定数据的选择条件;
GROUP BY子句用于对检索到的记录进行分组;
HAVING 子句用于指定组的选择条件;
ORDER BY 子句用于对查询的结果进行排序;
以上子句中,SELECT 子句和FROM子句是必需的,其它是可选的。



1.2 单表查询

1.2.1选择表中若干列

(1)查询指定的列

SELECT 列名 FROM 表名

例子 :SELECT Sname,Sno FROM Student

(2)查询全部列

SELECT * FROM 表名

例子 :SELECT * FROM Student

(3)查询经过计算的列

SELECT 列名 FROM 表名

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




1.2.2 选择表中的若干元祖

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

SELECT DISTINCT Sno FROM 表名

例子 :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可用于查找属性值在或不在指定范围。

列名 | 表达式 | [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运算符用于查找指定列中与匹配串匹配的元祖。

列名 [NOT] LIKE <匹配串>
通配符含义
_(下划线)匹配任意一个字符
%(百分号)匹配0个或多个字符
[]匹配[]中的任意一个字符。如[abcd]表示匹配abcd其中任何一个,若是连续的,可以用 - 表示,如[a-d]
[^]不匹配[]中的任意一个字符。如[^abcd]表示不匹配abcd其中任何一个,若是连续的,可以用 - 表示,如[^a-d]

例子 :

(查询姓“张”的学生详细信息)
SELECT * FROM Student WHERE Sname LIKE '张%'

(查询不姓“张”的学生详细信息)
SELECT * FROM Student WHERE Sname NOT LIKE '张%'

(查询姓“张”、“李”的学生详细信息)
SELECT * FROM Student WHERE Sname LIKE '[张李]%'

(查询名字的第二个字为“小” 或 “大”的学生详细信息)
SELECT * FROM Student WHERE Sname LIKE '_[小大]%'

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



1.2.3 对查询结果进行排序

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

ORDER BY <列名> [ASC|DESC]

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



1.2.4 使用聚合函数统计数据

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

聚合函数含义
COUNT(*)统计表中元祖的个数
COUNT([DISTINCT]<列名>)统计本列的非空列值个数
SUM(<列名>)计算列值的和值(必须是数值型列)
AVG(<列名>)计算列值的平均值(必须是数值型列)
MAX(<列名>)计算列值的最大值
MIN(<列名>)计算列值的最小值

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

(统计学生总人数)
SELECT COUNT(*) FROM Student

(统计“001”学号学生的考试平均成绩)
SELECT AVG(Grade) FROM SC WHERE Sno = '001'

(查询“C001”号课程考试成绩的最高分和最低分)
SELECT MAX(Grade) 最高分,MIN(Grade) 最低分 FROM SC WHERE Cno = 'C001'

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



1.2.5 对数据进行分组统计

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

GROUP BY <分组依据列>[,...n]
    [HAVING <组筛选条件>]

(1)使用GROUP BY 子句

(统计每门课程的选课人数,列出课程号和选课人数)
SELECT Cno as 课程号, COUNT(Sno) as 选课人数 From SC Group BY Cno

(统计每个学生的选课门数和平均成绩)
SELECT Sno 学号, COUNT(*)  选课门数,AVG(Grade) 平均成绩 From SC Group BY Sno

带WHERE子句的分组(统计每个系的女生人数)
SELECT Dept, COUNT(*)  女生人数 From Student Where Sex = '女' Group BY Dept

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

(查询选课门数超过3门的学生的学号和选课门数)
SELECT Sno 学号, COUNT(*)  选课门数,AVG(Grade) 平均成绩 From SC Group BY Sno HAVING COUNT(*) > 3

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

  • WHERE子句用于筛选FROM子句中指定的数据所产生的行数据。
  • GROUP BY 子句用于对经 WHERE 子句筛选后的结果数据进行分组。
  • HAVING 子句用于对分组后的统计结果再进行筛选。

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

(查询计算机系和信息管理系每个系的学生人数)
第一种:
SELECT Dept,COUNT(*) FROM Student GROUP BY Dept Having Dept in('计算机系','信息管理系')
第二种:
SELECT Dept,COUNT(*) FROM Student WHERE Dept in ('计算机系','信息管理系')GROUP BY Dept 

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





1.3 多表连接查询

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

1.3.1 内连接

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

FROM1 [INNER] JOIN2 ON <连接条件>

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

(查询学生及选课的详细信息)
SELECT * FROM Student INNER JOIN SC ON Student.Sno = SC.Sno

(查询计算机系学生的选课情况,列出该学生的名字、所修课程号、成绩)------行选择条件
SELECT Sname,Cno,Grade FROM Student INNER JOIN SC ON Student.Sno = SC.Sno WHERE Dept = '计算机系'

(统计每个系的平均成绩) ------分组的多表查询
SELECT Dept,AVG(Grade) AS AverageGrade FROM Student S INNER JOIN SC ON S.Sno = SC.Sno Group BY Dept

(统计计算机系每个学生的选课门数、平均成绩、最高成绩、最低成绩)------分组和行选择条件的多表连接查询
SELECT Sno,COUNT(*),AVG(Grade),MAX(Grade),MIN(Grade) FROM Student S JOIN SC ON S.Sno = SC.Sno WHERE Dept = '计算机系' Group BY Dept

1.3.2 自连接

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

FROM1 AS T1 JOIN1 AS T2

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

(查询与刘晨在同一个系学习的学生的姓名、所在系)
SELECT S1.Sname,S1.Dept FROM Student S1 JOIN Student S2 
ON S1.Dept = S2.Dept   ---同一个系的学生
WHERE S2.Sname = '刘晨'  ---S2表作为查询条件
AND S1.Sname != '刘晨'   ----S1表作为结果表,并从中去掉‘刘晨’本人信息

1.3.3 外连接

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

FROM 表1 LEFT|RIGHT [OUTER] JOIN2 ON <连接条件>

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


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

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

(查询没有人选的选修课程名)
SELECT Cname FROM Course C LEFT JOIN  SC ON C.Cno = SC.Cno WHERE SC.Cno IS NULL

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

(统计计算机系每个学生的选课门数,包括没选课的学生)
SELECT S.Sno AS 学号,COUNT(SC.Cno) AS 选课门数 FROM Student S LEFT JOIN SC ON S.Sno = SC.Sno WHERE Dept = '计算机系' GROUP BY S.Sno

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

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





1.4 使用TOP限制结果集行数

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

TOP (expression) [PERCENT] [WITH TIES]
  • expression:指定返回行数的数值表达式。如果指定了PERCENT,expression将隐式转换成float,否则是bigint
  • PERCENT:指定只返回结果集中前 expression% 行数据。
  • WITH TIES:指定从基本结果集中返回额外的数据行(只有在SELECT子句中包含了ORDER BY子句时,才能使用)。

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

(查询考试成绩最高的3个成绩。列出学号、课程号、成绩)
SELECT TOP 3 Sno,Cno,Grade FROM SC ORDER BY Grade DESC
若要包括并列第3名的成绩:
SELECT TOP 3 Sno,Cno,Grade WITH TIES FROM SC ORDER BY Grade DESC





2.数据更改功能

2.1 插入数据

INSERT INTO 表名[(列名)] VALUES (值)

(1)简单插入语句

INSERT INTO Student VALUES ('001','陈东','男','1996/6/23','信息管理系')

(2)多行插入语句

INSERT INTO SC VALUES('001','C001',90),
                     ('001','C002',30),
                     ('001','C005',NULL)

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

INSERT INTO Student(Sno,Sname,Sex,Dept) VALUES ('001','陈东','男','1996/6/23','信息管理系')




2.2 更新数据

UPDATE 表名 SET 列名 = 值

(1)无条件更新

UPDATE SC SET Grade = Grade+10

(2)有条件更新

(将“C001”号课程的学分改成5分)
UPDATE Course SET Grade = 5 WHERE Cno = 'C001'

(将计算机系全体学生的成绩加5分)
UPDATE SC SET Grade = Grade+5 FROM SC JOIN Student S ON S.Sno = SC.Sno WHERE Dept = '计算机系' 




2.3 删除数据

DELETE [TOP (expression) [PERCENT]]
    FROM 表名

(1)无条件删除

DELETE FROM Student

(2)有条件删除

(删除所有考试成绩不合格的学生的选课记录)
DELETE FROM SC WHERE Grade < 60

(删除Student表中2.5%的行数据)
DELETE TOP (2.5) PERCENT FROM Student






四. 高级查询

1. CASE函数

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

1.1 简单CASE函数

CASE input_expression
    WHEN when_expression THEN result_expression
    [...n]
    [ELSE else_expression]
END
  • input_expression:所计算的表达式,可以是一个变量名、字段名、函数或子查询。
  • when_expression :要与input _expression进行比较的简单表达式。简单表达式中不可包含比较运算法,只需给出被比较的表达式或值。
  • else_expression : 比较结果均不为TRUE时返回的表达式。
(查询选了JAVA课程的学生的学号、姓名、所在系、成绩,
若所在系为“计算机系”,则显示“CS”;若所在系为“信息管理系”,则显示“IM”;若所在系为“通信工程系”,则显示“COM”)
SELECT S.Sno 学号,Sname 姓名,
    CASE Dept
        WHEN '计算机系' THEN 'CS'
        WHEN '信息管理系' THEN 'IM'
        WHEN '通信工程系' THEN 'COM'
    END AS 所在系,Grade 成绩
    FROM Student S JOIN SC ON S.Sno = SC.Sno 
    JOIN Course C ON C.Cno = SC.Cno
    WHERE Cname = 'Java'

1.2 搜索CASE函数

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

CASE 
    WHEN Boolean_expression THEN result_expression
    [...n]
    [ELSE else_expression]
END
  • Boolean_expression :比较表达式,可以包含比较运算符,直接将两者进行比较。
上述例子也可以用搜索CASE函数:
SELECT S.Sno 学号,Sname 姓名,
    CASE 
        WHEN Dept = '计算机系' THEN 'CS'
        WHEN Dept = '信息管理系' THEN 'IM'
        WHEN Dept = '通信工程系' THEN 'COM'
    END AS 所在系,Grade 成绩
    FROM Student S JOIN SC ON S.Sno = SC.Sno 
    JOIN Course C ON C.Cno = SC.Cno
    WHERE Cname = 'Java'

(查询C001课程的考试情况,列出学号和成绩,然后根据成绩划分等级)
SELECT S.Sno 学号,Sname 姓名,
    CASE 
        WHEN Grade >= 90 THEN '优'
        WHEN Grade BETWEEN 80 AND 99 THEN '良'
        WHEN Grade BETWEEN 70 AND 79 THEN '中'
        WHEN Grade BETWEEN 60 AND 69 THEN '及格'
    END AS 成绩
    FROM  SC ON WHERE Cno = 'C001'




2. 子查询

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

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

  • 把一个查询分解成一系列的逻辑步骤
  • 提供一个列表作为WHERE子句和IN、EXISTS、ANY、ALL的目标对象
  • 提供由外层查询中每一条记录驱动的查询

子查询通常有几种形式:

  • WHERE 列名 [NOT] IN (子查询)
  • WHERE 列名 比较运算符 (子查询)
  • WHERE EXISTS(子查询)

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

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

SELECT <查询列表> FROM ...
WHERE <列名> [NOT] IN (
SELECT <列名> FROM)

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

(查询与刘晨在同一系的学生)
SELECT Sno,Sname,Dept FROM Student WHERE Dept IN
    (SELECT Dept From Student Where Sname = '刘晨')

(查询选修了JAVA课程学生的姓名)
SELECT Sname FROM Stduent WHERE Sno IN(
    SELECT Sno FROM SC WHERE Cno IN(
        SELECT Cno FROM Course WHERE Cname = 'JAVA'))

第二个例子也可以用了连接查询来做:
SELECT Sname From Student S JOIN SC ON S.Sno = SC.Sno JOIN Course C ON C.Cno = SC.Cno WHERE Cname = 'JAVA'

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

(统计选了JAVA 课程的学生的姓名和所在系)
子查询:
SELECT Sno 学号,COUNT(*) 选课门数,AVG(Grade) 平均成绩
    FROM SC WHERE Sno IN(
      SELECT Sno FROM SC JOIN Course C 
        ON C.Cno = SC.Cno
          WHERE Cname = 'JAVA')
     GROUP BY Sno

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

连接查询:

SELECT Sno 学号,COUNT(*) 选课门数,AVG(Grade) 平均成绩
        FROM SC JOIN Course C ON C.Cno = SC.Cno WHERE Cname = 'JAVA'       GROUP BY Sno

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




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

  • 之所以这样,是因为在执行有连接操作的查询时,系统首先将所有被连接的表连接成一张大表,这张大表中的数据全部满足连接条件的数据。之后再在这张连接后的大表上执行WHERE子句,然后是GROUP BY子句。

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

  • 对于含有嵌套的子查询的查询,是先执行子查询,然后在子查询的结果基础上再执行外层查询。



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

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

(查询没选C001课程的学生的姓名和所在系)

1.多表连接:
SELECT Sname,Dept FROM Student S JOIN SC ON S.Sno= SC。Sno WHERE Cno != 'C001'

2. 嵌套子查询:
1)在子查询中否定
SELECT Sname,Dept FROM Student
    WHERE Sno NOT IN(
      SELECT Sno FROM SC WHERE Cno = 'C001')

2)在外层查询中否定
SELECT Sname,Dept FROM Student
    WHERE Sno IN(
      SELECT Sno FROM SC WHERE Cno != 'C001')

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

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

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

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

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




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

SELECT <查询列表> FROM...
    WHERE <列名> 比较运算符 (
      SELECT <列名> FROM ...)

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

(查询选了C004 课程且成绩高于此课程的平均成绩的学生的学号和成绩)
SELECT Sno, Grade FROM SC
    WHERE Cno = 'C004' AND Grade >(
      SELECT AVG(Grade) FROM SC WHERE Cno = 'C004'



2.2 使用SOME 和 ALL 嵌套子查询

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

WHERE <列名> 比较运算符 [SOME | ALL](子查询)
(查询其他学期开设的课程中比第一学期开设课程的学分少的课程名、开课学期、学分)
SELECT Cname,Semester,Credit FROM Course
    WHERE Credit < SOME(
      SELECT Credit FROM Course
        WHERE Semester = 1)
AND Semester != 1

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

SELECT Cname,Semester,Credit FROM Course
    WHERE Credit < (
      SELECT MAX(Credit) FROM Course
        WHERE Semester = 1)
AND Semester != 1

(查询至少有一次成绩大于或等于90分的学生的学号及选修的全部课程的课程号和考试成绩)
SELECT Sname,Cno,Grade FROM Student S
    JOIN SC ON S.Sno = SC.Sno
     WHERE S.Sno = SOME (
      SELECT Sno FROM SC 
          WHERE Grade >= 90)

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

SELECT Sname,Cno,Grade FROM Student S
    JOIN SC ON S.Sno = SC.Sno
     WHERE S.Sno IN (
      SELECT Sno FROM SC 
          WHERE Grade >= 90)




未完待续……

希望对你们有帮助 :)

  • 118
    点赞
  • 562
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
轻轻松松学数据库!!SQL Server 2008是微软的SQL Server数据库中的最新版本,在该版本的数据库产品中融入了更多商业智能的内容。本书中也使用了一专门讲解了与商业智能有关的一些内容。 本书总分为5,共21章。第一主要讲解数据库基础,包括数据库的概念及安装。第二讲解数据库管理的常用知识,包括数据库的管理、表的管理、确保数据的完整性及用户权限的设置等内容。第三主要讲解SQL的编程,包括T-SQL语言、存储过程及触发器。第四讲解与商业智能有关的内容,包括集成服务、报表服务和分析服务。最后一是综合案例,分别使用.NET和Java语言实现了与SQL Server 2008的连接,并完成了图书管理系统和在线订餐系统。 第一 SQL Server 2008基础 第1章 学习数据库的准备 ( 教学视频:58分钟) 15 1.1 认识数据库 15 1.1.1 为什么要使用数据库 15 1.1.2 认识数据库产品 15 1.2 了解数据库对象 17 1.2.1 表 17 1.2.2 视图 17 1.2.3 索引 18 1.2.4 存储过程 18 1.2.5 触发器 18 1.3 认识SQL语言 18 1.3.1 什么是SQL 18 1.3.2 SQL语言的分类 19 1.4 绘制E-R图设计数据库 20 1.4.1 绘制E-R图的基本要素 20 1.4.2 E-R图绘制实例 22 1.5 小结 24 1.6 习题 24 第2章 数据库的安装 ( 教学视频:26分钟) 26 2.1 SQL Server 2008版本介绍 26 2.1.1 SQL Server 2008服务器版 26 2.1.2 SQL Server 2008专业版 26 2.2 SQL Server 2008环境需求 27 2.2.1 SQL Server 2008 Enterprise的 软硬件要求 27 2.2.2 SQL Server 2008 Enterprise Evaluation的软硬件要求 28 2.3 安装SQL Server 2008 29 2.3.1 自己动手安装SQL Server 2008 29 2.3.2 安装示例数据库 39 2.4 认识SQL Server Management Studio (企业管理器) 40 2.4.1 访问SQL Server Management Studio 40 2.4.2 SQL Server Management Studio 菜单简介 42 2.4.3 查询编辑器窗口 43 2.4.4 对象资源管理器 44 2.4.5 SQL编辑器 44 2.5 小结 45 2.6 习题 45 第二 SQL Server 2008管理 第3章 数据库操作 ( 教学视频:43分钟) 47 3.1 在SSMS中创建数据库 47 3.1.1 数据库命名需要注意的问题 47 3.1.2 数据库的所有者与权限 48 3.1.3 创建数据库 48 3.2 在SSMS中修改数据库配置 52 3.2.1 使用SSMS修改数据库配置的 通用步骤 52 3.2.2 在SSMS中添加数据库文件 53 3.2.3 在SSMS中删除数据库文件 53 3.2.4 修改数据库的所有者 55 3.2.5 限制用户的访问 56 3.2.6 设置用户对数据库的使用权限 57 3.2.7 修改数据库名称 59 3.3 使用SQL语句创建、修改、 删除数据库 59 3.3.1 用CREATE DATABASE语句 创建数据库 59 3.3.2 用ALTER DATABASE语句 修改数据库 60 3.3.3 用DROP DATABASE语句 删除数据库 62 3.4 附加与分离数据库 63 3.4.1 分离数据库 63 3.4.2 附加数据库 64 3.5 编写数据库脚本文件 66 3.6 综合练习 67 3.7 小结 69 3.8 习题 69 第4章 数据表操作 ( 教学视频:39分钟) 71 4.1 认识数据类型 71 4.1.1 字符型数据类型 71 4.1.2 数值型数据类型 72 4.1.3 日期和时间数据类型 73 4.1.4 其他数据类型 73 4.2 创建数据表 74 4.2.1 创建数据表的语法 74 4.2.2 创建主键 75 4.2.3 使用SSMS创建表 76 4.2.4 创建标识列 78 4.3 修改表结构 79 4.3.1 修改表结构的语法 80 4.3.2 在SSMS中修改表结构 82 4.4 表的删除、截断与重命名 82 4.4.1 使用SSMS删除和重命名表 83 4.4.2 使用DROP TABLE语句删除表 83 4.4.3 截断表 84 4.4.4 重命名表 85 4.5 小结 85 4.6 习题 85 第5章 确保数据完整性 ( 教学视频:89分钟) 87 5.1 认识约束 87 5.1.1 什么是约束 87 5.1.2 约束的类型 88 5.1.3 约束的语法 89 5.2 使用约束 90 5.2.1 利用SSMS创建主键约束 90 5.2.2 利用T-SQL增加主键约束 91 5.2.3 利用SSMS创建外键约束 92 5.2.4 利用T-SQL增加外键约束 93 5.2.5 利用SSMS工具创建CHECK 约束 94 5.2.6 利用T-SQL增加CHECK约束 95 5.2.7 利用SSMS工具删除约束 96 5.3 事务的使用 96 5.3.1 什么是事务 96 5.3.2 事务的特性 97 5.3.3 事务的模式类型 97 5.3.4 事务的保存点 99 5.4 并发控制 100 5.4.1 并发访问的问题 100 5.4.2 SQL Server中的锁 101 5.4.3 查看活跃事务 102 5.4.4 事务隔离级别 104 5.4.5 事务隔离级别的设置 104 5.5 事务的阻塞 105 5.6 死锁 107 5.6.1 死锁的产生 107 5.6.2 处理死锁 108 5.6.3 预防死锁 109 5.7 索引 109 5.7.1 认识索引 110 5.7.2 索引的创建 111 5.7.3 索引的管理 113 5.8 小结 115 5.9 习题 116 第6章 用户和权限管理 ( 教学视频:37分钟) 117 6.1 用户管理 117 6.1.1 创建使用Windows身份验证的 SQL Server 登录名 117 6.1.2 创建使用SQL Server身份验证的 SQL Server登录名 120 6.1.3 利用Transact-SQL创建 登录账号 121 6.1.4 创建数据库用户 122 6.1.5 使用Transact-SQL创建 数据库用户 123 6.1.6 登录账号和数据库用户的关系 124 6.2 认识角色 125 6.2.1 角色的划分 125 6.2.2 创建角色 127 6.2.3 给用户授予角色 128 6.3 认识权限 129 6.3.1 数据控制语言语法 129 6.3.2 给用户授予权限 131 6.4 架构 131 6.4.1 认识架构 132 6.4.2 架构的创建使用 133 6.4.3 架构的修改删除 134 6.5 小结 134 6.6 习题 135 第7章 数据的导入/导出与备份/恢复 ( 教学视频:27分钟) 136 7.1 了解SQL Server导入和导出向导 136 7.2 导入/导出数据 138 7.2.1 数据的导出 138 7.2.2 数据的导入 142 7.3 数据备份 145 7.3.1 认识数据备份 145 7.3.2 使用SSMS工具备份数据库 146 7.3.3 使用SSMS工具差异备份数据库 147 7.4 恢复数据 148 7.4.1 认识恢复数据 148 7.4.2 如何修改恢复模式 149 7.4.3 使用SSMS恢复数据库 150 7.5 小结 151 7.6 习题 151 第8章 使用SQL Server 2008中 自动化管理功能 ( 教学视频:20分钟) 153 8.1 认识SQL Server代理 153 8.1.1 什么是SQL Server 代理 153 8.1.2 使用SQL Server代理 154 8.2 认识作业 155 8.2.1 什么是作业 155 8.2.2 创建作业 156 8.2.3 管理作业 160 8.3 认识警报 163 8.3.1 创建警报 164 8.3.2 在警报中触发作业 165 8.3.3 管理警报 166 8.4 认识操作员 166 8.4.1 创建操作员 167 8.4.2 管理操作员 169 8.5 小结 169 8.6 习题 170 第9章 查询数据 ( 教学视频:64分钟) 171 9.1 在SSMS中查看数据 171 9.2 使用简单SELECT语句查询数据 171 9.2.1 查询表中所有数据 171 9.2.2 查询表中指定字段的数据 172 9.2.3 查询结果中去除重复信息 174 9.2.4 根据现有列值计算新列值 174 9.2.5 命名新列 175 9.2.6 将查询结果保存为新表 176 9.2.7 连接字段 177 9.3 使用SELECT语句获取满足查询 条件的数据 178 9.3.1 指针与字段变量的概念 178 9.3.2 条件表达式 179 9.3.3 WHERE子句用法 181 9.3.4 根据条件查询数值数据 182 9.3.5 根据条件查询字符数据 183 9.3.6 根据条件查询日期数据 184 9.3.7 按范围查询数据 185 9.3.8 查询NULL值 186 9.4 排序查询数据 186 9.4.1 按单列排序 187 9.4.2 设置排序方向 187 9.4.3 按多列排序 188 9.4.4 按字段位置排序 188 9.4.5 查询前5行数据 189 9.4.6 WHERE与ORDER BY的 结合使用 189 9.5 高级条件查询 190 9.5.1 AND运算符 190 9.5.2 OR运算符 191 9.5.3 AND与OR的优先顺序问题 192 9.5.4 NOT运算符 193 9.5.5 IN运算符 193 9.5.6 LIKE运算符与“%”通配符 195 9.5.7 “_”通配符的使用 197 9.5.8 “[]”通配符的使用 197 9.5.9 定义转义字符 198 9.6 小结 199 9.7 习题 199 第10章 函数与分组查询数据 ( 教学视频:42分钟) 201 10.1 系统函数 201 10.1.1 聚合函数 201 10.1.2 类型转换函数 202 10.1.3 日期函数 204 10.1.4 数学函数 206 10.1.5 字符函数 207 10.1.6 其他几个系统函数 208 10.2 分组查询 212 10.2.1 将表内容按列分组 212 10.2.2 聚合函数与分组配合使用 214 10.2.3 查询数据的直方图 215 10.2.4 排序分组结果 215 10.2.5 反转查询结果 216 10.2.6 使用HAVING子句设置 分组查询条件 217 10.3 小结 218 10.4 习题 218 第11章 多表连接查询和子查询 ( 教学视频:79分钟) 220 11.1 连接查询 220 11.1.1 使用无连接规则连接两表 220 11.1.2 使用有连接规则连接两表 221 11.1.3 使用多表连接查询数据 222 11.1.4 使用表别名简化语句 223 11.1.5 使用INNER JOIN连接查询 223 11.1.6 连接查询实例 224 11.2 高级连接查询 226 11.2.1 自连接查询 226 11.2.2 内连接查询 227 11.2.3 左外连接查询 229 11.2.4 右外连接 230 11.2.5 全外连接 230 11.2.6 交叉连接查询 230 11.2.7 连接查询中使用聚合函数 232 11.2.8 高级连接查询实例 233 11.3 组合查询 235 11.3.1 使用组合查询 236 11.3.2 使用UNION的规则 237 11.3.3 使用UNION得到复杂的统计 汇总样式 238 11.3.4 排序组合查询的结果 238 11.3.5 组合查询的实例 239 11.4 子查询 240 11.4.1 使用返回单值的子查询 240 11.4.2 子查询与聚合函数的配合使用 241 11.4.3 子查询的实例 241 11.5 在SSMS查询设计器中设计查询 242 11.6 综合练习 245 11.7 小结 246 11.8 习题 246 第12章 插入、更新和删除数据 ( 教学视频:39分钟) 248 12.1 在SSMS中插入、更新、删除数据 248 12.1.1 插入数据 248 12.1.2 更新数据 249 12.1.3 删除数据 249 12.2 使用INSERT语句插入数据 250 12.2.1 插入完整的行 250 12.2.2 向日期时间型字段插入数据 251 12.2.3 将数据插入到指定字段 251 12.2.4 将查询结果插入表 252 12.3 使用UPDATE语句更新数据 254 12.3.1 更新单个字段的数据 254 12.3.2 更新多个字段的数据 255 12.3.3 使用表连接更新数据 256 12.3.4 使用UPDATE语句删除 指定字段的数据 256 12.4 使用DELETE语句删除数据 257 12.4.1 使用DELETE语句删除 指定记录 257 12.4.2 在DELETE语句中使用 多表连接 258 12.4.3 使用DELETE语句删除 所有记录 259 12.5 使用TRUNCATE语句删除 所有记录 260 12.6 综合练习 260 12.7 小结 262 12.8 习题 263 第13章 视图 ( 教学视频:38分钟) 264 13.1 视图基础 264 13.2 视图的创建 266 13.2.1 在SSMS中创建视图 266 13.2.2 使用CREATE VIEW语句 创建视图 268 13.2.3 用别名命名视图字段 269 13.2.4 创建视图时的注意事项 270 13.2.5 创建加密视图 271 13.3 查看与修改视图 272 13.3.1 查看视图内容 272 13.3.2 在SSMS中修改视图 272 13.3.3 用ALTER VIEW修改视图 272 13.4 使用视图操作表数据 274 13.4.1 在SSMS中操作 视图中的数据 274 13.4.2 使用INSERT语句插入数据 274
--语 句 功 能   --数据操作   SELECT --从数据库表中检索数据行和列   INSERT --向数据库表添加新数据行   DELETE --从数据库表中删除数据行   UPDATE --更新数据库表中的数据   --数据定义   CREATE TABLE --创建一个数据库表   DROP TABLE --从数据库中删除表   ALTER TABLE --修改数据库表结构   CREATE VIEW --创建一个视图   DROP VIEW --从数据库中删除视图   CREATE INDEX --为数据库表创建一个索引   DROP INDEX --从数据库中删除索引   CREATE PROCEDURE --创建一个存储过程   DROP PROCEDURE --从数据库中删除存储过程   CREATE TRIGGER --创建一个触发器   DROP TRIGGER --从数据库中删除触发器   CREATE SCHEMA --向数据库添加一个新模式   DROP SCHEMA --从数据库中删除一个模式   CREATE DOMAIN --创建一个数据值域   ALTER DOMAIN --改变域定义   DROP DOMAIN --从数据库中删除一个域   --数据控制   GRANT --授予用户访问权限   DENY --拒绝用户访问   REVOKE --解除用户访问权限   --事务控制   COMMIT --结束当前事务   ROLLBACK --中止当前事务   SET TRANSACTION --定义当前事务数据访问特征   --程序化SQL   DECLARE --为查询设定游标   EXPLAN --为查询描述数据访问计划   OPEN --检索查询结果打开一个游标   FETCH --检索一行查询结果   CLOSE --关闭游标   PREPARE --为动态执行准备SQL 语句   EXECUTE --动态地执行SQL 语句   DESCRIBE --描述准备好的查询   ---局部变量   declare @id char(10)   --set @id = '10010001'   select @id = '10010001'   ---全局变量   ---必须以@@开头   --IF ELSE   declare @x int @y int @z int   select @x = 1 @y = 2 @z=3   if @x > @y   print 'x > y' --打印字符串'x > y'   else if @y > @z   print 'y > z'   else print 'z > y'   --CASE   use pangu   update employee   set e_wage =   case   when job_level = ’1’ then e_wage*1.08
SQL Server是由Microsoft公司开发的关系型数据库管理系统(RDBMS)。以下是SQL Server基础知识: 1. 数据库SQL Server是一个数据库管理系统,它可以管理多个数据库。每个数据库都是一个独立的实体,包含一组相关的表、视图、存储过程、触发器等。 2. 表:数据库中的数据存储在表中。表是一个二维的结构,由行和列组成。每个表都有一个名称,并且每个列都有一个数据类型。 3. 列:表中的列定义了表中存储的数据的类型。列可以是整数、字符、日期、时间等数据类型。 4. 行:表中的行是具体的数据。每行数据包含表中定义的所有列的值。 5. 主键:主键是一列或一组列,它们唯一地标识表中的每行数据。主键可以确保数据的唯一性和完整性。 6. 外键:外键是一列或一组列,它们与另一个表的主键相关联。外键用于确保数据的一致性和完整性。 7. 视图:视图是一种虚拟的表,它不实际存储数据。视图是从一个或多个表中选择数据的查询结果集。 8. 存储过程:存储过程是一组预定义的SQL语句,可以在需要时调用它们。存储过程可以接受输入参数,并返回输出参数。 9. 触发器:触发器是一种特殊类型的存储过程,当特定的事件发生时自动执行。触发器可以在数据插入、更新或删除时触发。 10. 索引:索引是一种特殊的结构,用于加快数据的检索和查询速度。索引可以是唯一的,也可以是非唯一的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值