SQL查询语言

1 SQL概述

SQL:结构化查询语言(structured query language)。由4部分组成

  1. 数据定义语言(data definition language,DDL):主要用于定义数据库的逻辑结构,包括数据库、基本表、视图、索引等。DDL包括三类语言:定义、删除、修改
  2. 数据操纵语言(data manipulation language,DML):主要用于对数据库的数据进行检索和更新,更新包括:插入、删除和修改数据
  3. 数据控制语言(data control language,DCL):主要用于对数据库的对象进行授权、用户维护(包括创建、修改、删除)、完整性规则定义和事务定义
  4. 其他:主要是嵌入式SQL语言和动态SQL语言的定义,规定了SQL语言在宿主语言中使用的规则

数据查询:SELECT
数据定义:CREATE,DROP,ALTER
数据更新:INSERT,DELETE,UPDATE
数据控制:GRANT,REVOKE

2 基本语法

SQL查询语句 SELECT共有6个子句,其中SELECT 和 FROM是必需的,
其他是可选项,它们必须严格按照如下顺序排列。
********************************************************
SELECT [ALL|DISTINCT] <目标列表达式>[[AS]<别名>]
					[,<目标列表达式>[[AS]<别名>]…]
FROM <表名|视图名|查询表>[[AS]<别名>]
  [,<表名|视图名|查询表>[[AS]<别名>]…]
[WHERE <条件表达式>]
[GROUP BY <列名1>[,<列名2>…]
[HAVING <条件表达式>]]
[ORDER BY <列名表达式>[ASC|DESC][,<列名表达式>[ASC DESC]…]]
********************************************************
说明:
<>(尖括号)表示替换语法项,使用时不要输入尖括号,
			如<表名>使用时可替换为Score;
[](方括号)表示可选语法项,使用时不要输入方括号;
{}(大括号)表示必选语法项,使用时不要输入大括号;
| (竖线)表示或选语法项(只能选择其中一项),如ALL|DISTINCT表示
			只能选择 ALL或 DISTINCT使用,缺省表示选择ALL;
… (省略号)表示重复语法项,它必须出现在可选语法项中,表示
			该可选语法项中位于省略号左边的所有内容可重复多次。

3 查询操作

数据库关系图

--*************************数据库脚本*********************************
--若同名数据库已存在,则删除重新创建
--**********************************************************************
USE MASTER
GO

DECLARE @dbname SYSNAME
SET @dbname = 'ScoreDB' --这个是要删除的数据库库名
DECLARE @s NVARCHAR(1000)

DECLARE tb CURSOR LOCAL FOR
	SELECT s = 'kill ' + CAST(spid AS VARCHAR)
	FROM MASTER..sysprocesses
	WHERE dbid = DB_ID(@dbname)
OPEN tb
FETCH NEXT FROM tb INTO @s
WHILE @@fetch_status = 0
BEGIN
	EXEC (@s)
	FETCH NEXT FROM tb INTO @s
END
CLOSE tb
DEALLOCATE tb

EXEC ('drop database [' + @dbname + ']')

--**********************************************************************
--创建“学生成绩管理数据库”(ScoreDB)
--**********************************************************************
SET NOCOUNT ON 
USE master
GO
IF EXISTS (SELECT * FROM sysdatabases WHERE NAME='ScoreDB')
  DROP DATABASE ScoreDB
GO

PRINT 'creat database ScoreDB'
CREATE DATABASE ScoreDB
ON								--定义数据文件
	( NAME=ScoreDB_data,		--逻辑文件名
								--物理文件名
	  FILENAME='G:\ProgramFiles\MSSQL14.SQLEXPRESS01\MSSQL\DATA\ScoreDB_data.mdf' ,
	  SIZE=10,					--文件初始大小为5MB
	  MAXSIZE=200,				--文件最大为200MB
	  FILEGROWTH=5				--增量为5MB
	)
LOG ON							--定义日志文件
	( NAME=ScoreDB_log,			--逻辑文件名
	  FILENAME='G:\ProgramFiles\MSSQL14.SQLEXPRESS01\MSSQL\DATA\ScoreDB_log.ldf' ,
								--物理文件名
	  SIZE=10,					--文件初始大小为5MB
	  MAXSIZE=200,				--文件最大为200MB
	  FILEGROWTH=5				--增量为5MB
	)
GO

USE ScoreDB
GO

DROP TABLE IF EXISTS [dbo].[Course]
GO
CREATE TABLE Course
(
	courseNo	char(3)					NOT NULL,	--课程号
	courseName	varchar(30)	UNIQUE		NOT NULL,	--课程名
	creditHour	numeric(1)	DEFAULT 0	NOT NULL,	--学分
	courseHour	tinyint		DEFAULT 0	NOT NULL,	--课时数
	priorCourse char(3)					NULL,		--先修课程
	CONSTRAINT CoursePK PRIMARY KEY (courseNo),
	FOREIGN KEY (priorCourse) REFERENCES Course(courseNo)
);
GO

insert into Course values('001','大学语文',2,32,null)
insert into Course values('002','体育',    2,32,null)
insert into Course values('003','大学英语',3,48,null)
insert into Course values('004','高等数学',6,96,null)
insert into Course values('005','C语言程序设计',4,80,'004')
insert into Course values('006','计算机原理',4,64,'005')
insert into Course values('007','数据结构',5,96,'005')
insert into Course values('008','操作系统',4,64,'007')
insert into Course values('009','数据库系统原理',4,80,'008')
insert into Course values('010','会计学原理',4,64,'004')
insert into Course values('011','中级财务会计',5,80,'010')
GO

DROP TABLE IF EXISTS [dbo].[Class]
GO
CREATE TABLE Class
(
	classNo		char(6)					NOT NULL,	--班级号
	className	varchar(30)	UNIQUE		NOT NULL,	--班级名
	institute	varchar(30)				NOT NULL,	--所属学院
	grade		smallint	DEFAULT 0	NOT NULL,	--年级
	classNum	tinyint					NULL,		--班级人数
	CONSTRAINT ClassPK PRIMARY KEY (classNo)
);
GO

insert into Class values('CS1501','计算机科学与技术15-01班','信息管理学院',2015,null)
insert into Class values('CS1502','计算机科学与技术15-02班','信息管理学院',2015,null)
insert into Class values('IS1501','信息管理与信息系统15-01班','信息管理学院',2015,null)
insert into Class values('IS1601','信息管理与信息系统16-01班','信息管理学院',2016,null)
insert into Class values('CP1601','注册会计16_01班','会计学院',2016,null)
insert into Class values('CP1602','注册会计16_02班','会计学院',2016,null)
insert into Class values('CP1603','注册会计16_03班','会计学院',2016,null)
insert into Class values('ER1501','金融管理15-01班','金融学院',2015,null)
insert into Class values('CS1601','计算机科学与技术16-01班','信息管理学院',2016,null)
GO

DROP TABLE IF EXISTS [dbo].[Student]
GO
CREATE TABLE Student
(
	studentNo	char(7)						NOT NULL    --学号
		CHECK (studentNo LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][0-9]'),	
	studentName varchar(20)					NOT NULL,	--姓名
	sex			char(2)						NULL,		--性别
	birthday	datetime					NULL,		--出生日期
	native		varchar(20)					NULL,		--籍贯
	nation		varchar(30)	DEFAULT '汉族'	NULL,		--民族
	classNo		char(6)						NULL,		--所属班级
	CONSTRAINT StudentPK PRIMARY KEY (studentNo),
	CONSTRAINT StudentFK FOREIGN KEY (classNo) REFERENCES Class(classNo)
);
GO

insert into Student values('1600001','李勇',   '男','1998-12-21 00:00','南昌','汉族',   'CS1601')
insert into Student values('1600002','刘晨',   '女','1998-11-11 00:00','九江','汉族',   'IS1601')
insert into Student values('1600003','王敏',   '女','1998-10-01 00:00','上海','汉族',   'IS1601')
insert into Student values('1600004','张立',   '男','1999-05-20 00:00','南昌','蒙古族', 'CS1601')
insert into Student values('1600005','王红',   '男','1999-04-26 00:00','南昌','蒙古族', 'CP1602')
insert into Student values('1600006','李志强', '男','1999-12-21 00:00','北京','汉族',   'CP1602')
insert into Student values('1600007','李立',   '女','1999-08-21 00:00','福建','畲族',   'IS1601')
insert into Student values('1600008','黄小红', '女','1999-08-09 00:00','云南','傣族',   'CS1601')
insert into Student values('1600009','黄勇',   '男','1999-11-21 00:00','九江','汉族',   'CP1602')
insert into Student values('1600010','李宏冰', '女','1998-03-09 00:00','上海','汉族',   'CP1602')
insert into Student values('1600011','江宏吕', '男','1998-12-20 00:00','上海','汉族',   'CP1602')
insert into Student values('1600012','王立红', '男','1998-11-18 00:00','北京','汉族',   'CS1601')
insert into Student values('1600013','刘小华', '女','1999-07-16 00:00','云南','哈呢族', 'IS1601')
insert into Student values('1600014','刘宏昊', '男','1999-09-16 00:00','福建','汉族',   'IS1601')
insert into Student values('1600015','吴敏',   '女','1997-01-20 00:00','福建','畲族',   'CP1602')
insert into Student values('1500001','李小勇',   '男','1998-12-21 00:00','南昌','汉族',   'CS1501')
insert into Student values('1500002','刘方晨',   '女','1998-11-11 00:00','九江','汉族',   'IS1501')
insert into Student values('1500003','王红敏',   '女','1997-10-01 00:00','上海','汉族',   'IS1501')
insert into Student values('1500004','张可立',   '男','1999-05-20 00:00','南昌','蒙古族', 'CS1501')
insert into Student values('1500005','王红',   '男','2000-04-26 00:00','南昌','蒙古族',   'CS1502')
GO

DROP TABLE IF EXISTS [dbo].[Term]
GO
CREATE TABLE Term
(
	termNo	 char(3)					NOT NULL,	--学期号
	termName varchar(30)				NOT NULL,	--学期描述
	remarks  varchar(10)				NULL,		--备注
	CONSTRAINT TermPK PRIMARY KEY (termNo)
);
GO

insert into  Term values('151','2015-2016学年第一学期',null)
insert into  Term values('152','2015-2016学年第二学期',null)
insert into  Term values('153','2015-2016学年第三学期','小学期')
insert into  Term values('161','2016-2017学年第一学期',null)
insert into  Term values('162','2016-2017学年第二学期',null)
insert into  Term values('163','2016-2017学年第三学期','小学期')
GO
  
DROP TABLE IF EXISTS [dbo].[Score]
GO
CREATE TABLE Score
(
	studentNo char(7)					NOT NULL,	--学号
	courseNo char(3)					NOT NULL,	--课程号
	termNo char(3)						NOT NULL,	--学期号
	score numeric(5,1) DEFAULT 0		NOT NULL
	CHECK (score BETWEEN 0.0 AND 100.0),			--成绩
	CONSTRAINT ScorePK PRIMARY KEY (studentNo, courseNo, termNo),
	CONSTRAINT StudentFK1 FOREIGN KEY (studentNo) REFERENCES Student(studentNo),
	CONSTRAINT StudentFK2 FOREIGN KEY (courseNo) REFERENCES Course(courseNo),
	CONSTRAINT StudentFK3 FOREIGN KEY (termNo) REFERENCES Term(termNo)
);
GO

insert into Score values('1500001','001','151',98)
insert into Score values('1500001','002','151',82)
insert into Score values('1500001','010','151',86)
insert into Score values('1500001','004','151',56)
insert into Score values('1500001','005','152',77)
insert into Score values('1500001','006','152',76)
insert into Score values('1500001','007','152',77)
insert into Score values('1500001','004','161',86)
insert into Score values('1500001','003','161',82)
insert into Score values('1500001','008','161',82)
insert into Score values('1500001','009','162',77)

insert into Score values('1500005','002','151',80)
insert into Score values('1500005','003','151',69)
insert into Score values('1500005','004','151',87)
insert into Score values('1500005','005','151',77)
insert into Score values('1500005','001','152',79)
insert into Score values('1500005','006','152',69)
insert into Score values('1500005','010','152',69)
insert into Score values('1500005','007','161',90)
insert into Score values('1500005','008','161',87)
insert into Score values('1500005','009','162',90)
insert into Score values('1500005','011','162',68)

insert into Score values('1500003','005','151',60)
insert into Score values('1500003','001','151',46)
insert into Score values('1500003','002','151',38)
insert into Score values('1500003','007','152',50)
insert into Score values('1500003','002','152',58)
insert into Score values('1500003','006','161',70)
insert into Score values('1500003','010','161',90)
insert into Score values('1500003','007','162',66)
insert into Score values('1500003','008','162',82)
insert into Score values('1500003','009','162',78)

insert into Score values('1500004','001','151',48)
insert into Score values('1500004','004','151',58)
insert into Score values('1500004','003','152',70)
insert into Score values('1500004','002','161',68)
insert into Score values('1500004','007','161',71)
insert into Score values('1500004','008','161',80)
insert into Score values('1500004','001','162',70)
insert into Score values('1500004','005','162',88)
insert into Score values('1500004','006','162',72)

insert into Score values('1600002','001','161',98)
insert into Score values('1600002','004','161',60)
insert into Score values('1600002','002','161',46)
insert into Score values('1600002','003','162',98)
insert into Score values('1600002','010','162',70)
insert into Score values('1600002','005','162',86)

insert into Score values('1600003','001','161',70)
insert into Score values('1600003','002','161',60)
insert into Score values('1600003','004','161',77)
insert into Score values('1600003','005','162',87)

insert into Score values('1600004','001','161',50)
insert into Score values('1600004','002','161',70)
insert into Score values('1600004','004','161',78)
insert into Score values('1600004','010','161',89)
insert into Score values('1600004','011','162',90)
insert into Score values('1600004','003','162',88)
insert into Score values('1600004','001','162',68)

insert into Score values('1600005','001','161',82)
insert into Score values('1600005','002','161',80)
insert into Score values('1600005','010','161',90)
insert into Score values('1600005','004','161',47)
insert into Score values('1600005','003','162',82)
insert into Score values('1600005','011','162',82)

insert into Score values('1600014','001','161',60)
insert into Score values('1600014','003','161',87)
insert into Score values('1600014','004','161',45)
insert into Score values('1600014','010','161',90)
insert into Score values('1600014','004','162',88)
insert into Score values('1600014','011','162',70)
insert into Score values('1600014','002','162',69)
insert into Score values('1600014','005','162',56)

insert into Score values('1600012','001','161',68)
insert into Score values('1600012','003','161',76)
insert into Score values('1600012','004','161',70)
insert into Score values('1600012','005','161',88)
insert into Score values('1600012','002','162',78)
insert into Score values('1600012','006','162',82)
insert into Score values('1600012','007','162',90)
insert into Score values('1600012','010','162',84)
GO

3.1 单表查询

3.1.1 投影运算

1 查询指定列

SELECT classNo, className
FROM Class

2 消除重复元组

SELECT DISTINCT institute
FROM Class

3 查询所有列

SELECT classNo, className, classNum, grade, institute
FROM Class
或
SELECT * 
FROM Class

4 给属性列取别名

SELECT institute [AS] 所属学院,classNo [AS] 班级编号, className [AS] 班级名称
FROM Class

5 查询经过计算的列

SELECT courseNo 课程号,lower(courseName)课程名,courseHour/16 周课时
FROM Course

3.1.2 选择运算

WHERE字句可以实现关系代数中的选择运算,用于查询满足选择条件的元组,是查询中涉及最多的一类查询。WHERE字句常用的查询条件运算符:
 

扫描二维码关注公众号,回复: 9009216 查看本文章
  • 比较运算:>,>=,<,<=,=,<>(!=)
  • 范围查询:[NOT] BETWEEN……AND
  • 集合查询:[NOT] IN
  • 空值查询:IS [NOT] NULL
  • 字符匹配查询:[NOT] LIKE
  • 存在量词运算符:[NOT] EXISTS
  • 逻辑查询:AND,OR,NOT
     

1 比较运算

SELECT classNo, className, institute
FROM Class
WHERE grade=2015

2 范围查询

SELECT studentNo, courseNo, score
FROM Score
WHERE score BETWEEN 80 AND 90

3 集合查询

SELECT studentNo, courseNo, score
FROM Score
WHERE courseNo IN ('001', '003', '005')

4 空值查询

SELECT *
FROM Course
WHERE priorCourse IS NOT NULL

5 字符匹配查询
通配符(%和_):
%:表示任意长度的字符串
_:表示任意一个字符
语法格式:
[NOT] LIKE <匹配字符串> [ESCAPE <换码字符>]

SELECT * 
FROM Class
WHERE calssName LIKE '%计算机%'

SELECT * 
FROM Student
WHERE studentName LIKE '王__'

6 逻辑运算

SELECT *
FROM Score
WHERE courseNo='001' AND courseNo='002'

3.1.3 排序运算

语法:ORDER BY <表达式 1> [ASC | DESC] [, <表达式 2> [ASC | DESC] ……]
若未指明,按升序(ASC)排序;要按降序排序,需明确指明DESC。
下例按班级编号升序,出生日期降序排序:

SELCT studentNo, studentName, classNo, birthday
FROM Student
WHERE sex='女'
ORDER BY classNo, month(birthday) DESC

3.1.4 查询表

SQL中的FROM字句后面除了基本表、视图,还可以是查询表

SELECT studentNo, studentName, birthday
FROM (SELECT * FORM Student WHERE sex='女') [AS] a
WHERE year(birthday)=1999
该查询等价于:
SELECT studentNo, studentName, birthday
FROM Student 
WHERE year(birthday)=1999 AND  sex='女'

3.1.5 聚合查询

1 聚合函数

聚合函数可以直接使用在HAVING子句 / 子查询中,但在WHERE子句中不能直接使用聚合函数。(子查询:见本文3.3节)

SQL查询集合函数(aggregate function)主要有:

  • count([DISTINCT | ALL] {* | <列名>}):统计关系的元组个数或一列中值的个数
  • sum([DISTINCT | ALL] <列名>):统计一列中值的总和(系列必须为数值型)
  • avg([DISTINCT | ALL] <列名>):统计一列中值的平均值(系列必须为数值型)
  • max([DISTINCT | ALL] <列名>):统计一列中值的最大值
  • min([DISTINCT | ALL] <列名>):统计一列中值的最小值
SELECT COUNT(*)
FROM Student

SELECT COUNT(studentNo) 学生人数
FROM Student

2 分组聚合

在 SQL查询中,往往需要对数据进行分类运算(即分组运算),分组运算的目的是为了细化聚合函数的作用对象。如果不对查询结果进行分组,则聚合函数作用于整个查询结果;如果对查询结果进行分组,则聚合函数分别作用于每个组,查询结果是按组聚合输出。SQL语句中通过使用GROUP BY 和 HAVING子句来实现分组运算,其中:

  • GROUP BY子句对查询结果按某一列或某几列进行分组,值相等的分为一组;
  • HAVING子句对分组的结果进行选择,仅输出满足条件的组。该子句必须与GROUP BY子句配合使用。

WHERE 和 HAVING字句的区别:

  • WHERE子句:作用于整个查询对象,对元组进行过滤
  • HAVING子句:仅作用于分组,对分组进行过滤
SELECT studentNo, COUNT(*) 门数,AVG(score)平均分, MAX(score)最高分
FROM Score
GROUP BY studentNo

SELECT studentNo, COUNT(*) 门数,AVG(score)平均分, MAX(score)最高分
FROM Score
GROUP BY studentNo
HAVING AVG(score)>= 80

注意:查询语句中若使用了GROUP BY字句,则SELECT列表中未使用聚合函数的属性列全都应包含在GROUP BY字句中
如上例中:SELECT 后只有studentNo未使用聚合函数,所以它被包含在GROUP BY子句中,若有其它的,则同样处理。

3.2 连接查询

连接运算是关系数据库中使用最广泛的一种运算。

3.2.1 等值连接

SELECT studentName, native, Student.classNo, className
FROM Student, Class
WHERE Student.classNo=Class.classNo AND institute='会计学院'
或
SELECT studentName, native, Student.classNo, className
FROM Student [AS] a, Class [AS] b
WHERE a.classNo=b.classNo AND institute='会计学院'

3.2.2 自表连接

若某个表与自己进行连接,称为自表连接。

SELECT a.studentName, a.classNo, a.birthday
FROM Student a, Student b
WHERE b.studentName='张三' AND a.classNo=b.classNo

3.2.3 外连接

使用LEFT OUTER JOIN,左表的记录将全部显示,ON后的限制条件对左表不起作用,除非使用WHERE子句;ON后的限制条件对右表中的记录有限制作用。右外连接反之。

1 左外连接

左外连接的连接结果中包含左关系中的所有元组,对于左关系没有连接上的元组,其右关系中的相应属性用空值代替。

SELECT className, institute, studentNo, studentName
FROM Class a LEFT OUTER JOIN Student b ON a.classNo=b.classNo
WHERE grade=2015
ORDER BY className, studentNo

2 右外连接

右外连接的连接结果中包含左关系中的所有元组,对于右关系没有连接上的元组,其左关系中的相应属性用空值代替。

SELECT className, institute, studentNo, studentName
FROM Class a RIGHT OUTER JOIN Student b ON a.classNo=b.classNo
WHERE grade=2015
ORDER BY className, studentNo

3 全外连接

全外连接结果中包含左右关系中的所有元组,对于左关系没有连接上的元组,其右关系中的相应属性用空值代替;对于右关系没有连接上的元组,其左关系中的相应属性用空值代替。

SELECT className, institute, studentNo, studentName
FROM Class a FULL OUTER JOIN Student b ON a.classNo=b.classNo
WHERE grade=2015
ORDER BY className, studentNo

3.3 嵌套子查询

在SQL查询中,一个SELECT-FROM-WHERE查询语句称为一个查询块,将一个查询块嵌入到另一个查询块的WHERE / HAVING子句中,称为嵌套子查询。

3.3.1 使用IN的子查询

SELECT a.studentNo, studentName, courseName, score
FROM Student a, Course b, Score c
WHERE a.studentNo=c.studentNo 
	AND b.courseNo=c.courseNo
	AND a.studentNo IN (SELECT studentNo FROM Score x, Course y
					    WHERE x.courseNo=y.courseNo 
					    	AND courseName='计算机原理')
ORDER BY a.studentNo, score DESC

3.3.2 使用比较运算符的子查询

在这里插入图片描述

SELECT studentNo, courseNo, score
FROM Score
WHERE score>ALL
	(SELECT score
 	 FROM Score
	 WHERE courseNo='002')

3.3.3 使用存在量词EXISTS的子查询

SELECT studentName, className
FROM Student x
WHERE EXISTS
	(SELECT * 
	 FROM Score a, Course b
	 WHERE a.courseNo=b.courseNo
		AND a.studentNo=x.studentNo 
		AND courseName='计算机原理')

相关子查询在SQL中属于复杂的查询,其子查询的查询条件依赖于外层c查询的元组值.当外层查询的元组值发生变化时,其子查询要重新依据新的条件进行查询,因此使用存在量词 EXISTS的相关子查询的处理过程是:

  1. 首先取外层查询的第一个元组
  2. 依据该元组的值,执行子查询
  3. 如果子查询的结果非空(即EXISTS量词返回真值),将外层查询的该元组放入到结果集中;否则(即EXISTS量词返回假值),舍弃外层查询的该元组
  4. 取外层查询的下一个元组,返回第2步重复上述过程,直到外层查询所有的元组处理完毕
  5. 将结果集合中的元组作为一个新关系输出
发布了50 篇原创文章 · 获赞 38 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42250302/article/details/103100815