数据查询、视图、索引及连接操作
ANSI SQL 的select语句
ANSI是一种字符代码,为使计算机支持更多语言,通常使用 0x00~0x7f 范围的1 个字节来表示 1 个英文字符。超出此范围的使用0x80~0xFFFF来编码,即扩展的ASCII编码。
语法:
SELECT [ALL][DISTINCT] select_list
[FROM table_name[,...]]
[WHERE search_conditions
|(SELECT subquery_select_list [FROM table_name[,...]
[WHERE search_conditions])]
[GROUP BY aggregate_free_expression[,...]]
[HAVING search_conditions]
[ORDER BY{[table_name.]column_name|
select_list_number|expression} [ASC|DESC][,...]]
选择指定的列
我们可以在 select 关键字后跟一个或多个表列。星号指示 SQL Server 显示表中的所有 字段。我们使用同样的 select 语句,可以指定需要查看的一个表的某些字段。
条件查询
带and/or的where 子句:逻辑操作符and和or
- or:当所连接的两个条件之一为真值返回true
- and:当所连接的两个条件都为真时返回true
带 NOT 的 where 子句
SQL Sever 支持否定条件的搜索。
如:查询所有年龄在 20 岁以下的学生姓名及其年龄。
Select Sname,Sage from Student where NOT Sage>=20。
带检索范围的 where 子句
SQL Sever 也支持限定范围的检索。BETWEEN…AND…和 NOT BETWEEN…AND…来实现
此功能。如:查询年龄在20至30岁之间的学生姓名、系别和年龄。
Select Sname,Sdept,Sage from Student where Sage BETWEEN 20 AND 23;
带检索集合的 where 子句
IN可以用来查找属性值属于指定集合的行。
如:查询计算机系 (CS)和数学系
(MA)的学生的姓名和性别。
Select Sname,Ssex from Student where Sdept IN (‘计算机学院’,’光电学院’);
where 子句中的常用操作符
查询条件 谓词 比较 =,<,>,<=,>=,<>,!>,!<,not 确定范围 between and,not between and 确定集合 in,not in 多重条件 and,or
SQL 关于 LIKE 子句和通配符的扩充
LIKE 谓词
在 SELECT 语句的 WHERE 子句或 HAVING 子句中,使用 like 谓词来确定可能包含通配符的字符串匹配的数据。
ANSI-SQL 标准中的通配符
- %表示任意多个字符的字符串,也可以没有字符。
- _表示任一个字符。
T-SQL 对通配符的扩充
[]
表示任意在给定范围或集合内的单个字符如[a-m]表示按字母顺序从 a 到 m 中的任意一个小写字母。
[^]
表示任意不在给定范围或集合内的单个字符。如
[^a-m]
表示除按字母顺序从 a到 m 中任一小写字母外的任意一个字符。
Order by 子句
对查询结果进行升序排序或降序排序。
语法(默认升序)
<start of select statement>
Order by{column_name| expression|select_list_nm} [ASC|DESC],...
<end of select statement>
例 2:列出所有学生的信息,并按学生的出生日期排降序:
Select title from titles Order by price desc
分组计算函数(聚集函数)
函数 | 返回 | 例子 |
---|---|---|
sum(column_name) | column_name列的所有值的和 | select sum(sales)from customer |
avg(column_name) | column_name列的所有值的平均值 | select avg(sales)from customer |
count(*) | 表中数据行数目 | select count(* )from customer |
max(column_name) | 存放在column_name列的最大值 | select max(sales)from customer |
min(column_name) | 存放在column_name列的最小值 | select max(sales)from customer |
使用 Group by 子句
Group by 子句可以将查询结果表的各行按一列或多列取值相等的原则进行分组。对查询结果分组的目的是为了细化聚集函数的作用对象。
如果未对查询结果分组,聚集函数将作用于整个查询结果,即整个查询结果只有一个函数值,否则,聚集函数将作用于每一个组, 即每一组都有一个函数值。
如:查询各个课程名称与相应的选课人数。
Select Cname,count(Sno) from SC c,Cname d where c.Cno=d.Cno group by d.cname
使用 having 子句
正如为单行查询设置查询条件 state_cd=”MA”那样,也可以使用 having 子句,为一组记录设置查询的条件。
如:要查询计算机系选修了 3 门以上课程的学生的学号。(SC 为学生 选课表,为简单起见设 SC 表中有一列 Dept)
Select Sno from SC where Dept=’CS ’group by Sno having count(*)>3
注:Where 子句与 having 子句的根本区别在于作用对象不同。Where 子句作用于基本表或视图,从中选择满足条件的行。Having 子句作用于组,从中选择满足条件的组。
数学函数
ifnull()函数
ifnull()函数是一个系统函数。当指定的表达式为空值时,用指定的值代替。 语法 Ifnull(expression,value)
注:expression 为指定的被判别是否为 null 值的表达式。
value 为指定将代替空值的替换值。
例 6:计算所有书的平均单价,包括未定价的书,未定价的书的价格用$0代替:
Select avg(ifnull(price,$0)) from titles
嵌套查询
在SQL语言中,一个select-from-where语句称为一个查询块。将一个查询快嵌套在另 一个查询块的 where 子句或 having 子句的条件中的查询称为嵌套查询或子查询。
子查询的格式如下:
{main query text{where{
condition} ({sub query text})
例如下面的查询访问的是 customer 表,而子查询访问的是 state 表:
Select last_name,sales From customer Where state_cd=(selec max(state_cd) from
state)
基本连接
命令格式如下:
Select columns From tables Where join condition is…
等值连接(Equi-join)
等值连接用“=”操作符。
如连接基表 EMP 和 DEPT:
SELECT ENAME,JOB,DNAME FROM EMP,DEPT WHERE EMP.DEPTNO=DEPT.DEPTNO
非等值连接(Non-equi-join)
非等值连接可用 BETWEEN,IN,>,>=,<,<=等操作符。
创建视图
视图的主要功能:
将用户限定在表中的特定行上。
例如,只允许雇员看见工作跟踪表内记录其工作的行。
将用户限定在特定列上。
例如,对于那些不负责处理工资单的雇员,只允许他们看见雇员表中的姓名列、办公室列、 工作电话列和部门列,而不能看见任何包含工资信息或个人信息的列。
将多个表中的列联接起来,使它们看起来象一个表。
聚合信息而非 供详细信息。
例如,显示一个列的和,或列的最大值和最小值。
建立视图的语法:
CREATE VIEW [ < database_name > .] [ < owner > .] view_name [ ( column [ ,...n ] ) ] [ WITH < view_attribute > [ ,...n ] ] AS select_statement [ WITH CHECK OPTION ] < view_attribute > ::= { ENCRYPTION | SCHEMABINDING | VIEW_METADATA }
使用视图
使用视图进行查询,与表的查询一样.
例:使用例 1 创建的视图 stcourse 查询所有学生的选课情况。
select * from stcourse 通过视图修改数据:insert, update, delete 语句
修改和删除视图
视图的更新:
Alter view view_name As Select_statement
删除视图:
DROP VIEW View_name
索引
索引是为了加速对表中的数据行的检索而创建的一种存储结构。
注意:
建立索引要花费时间,并且占用存储空间。 建索引能加快检索速度,但是会减慢数据修改速度。
索引的类型
按索引的列数是单列还是多列
- 单列索引:只有一列进行索引
- 组合索引:由多列组成的索引
按索引关键字值是否有重复值
- 唯一(unique)索引
- 非唯一索引:索引的列值可以有重复值,如年龄索引
按照索引的顺序和数据库的物理存储顺序是否相同,可分为
- 聚集索引(CLUSTERED):也叫簇索引,会改变表中的记录的物理存储顺序,表的 记录不再按输入记录的先后排列,而是按索引的顺序存放。
- 非聚集索引(NONCLUSTERED):表中记录的物理存储顺序并不改变,系统将使用索 引页来创建一个索引结构,用以表示行的逻辑顺序。
索引的优点:
正确的索引会大大 高数据查询,对结果进行排序、分组的操作效率。
索引的缺点:
创建索引需要额外的磁盘空间,索引最大一般为表大小的1.2 倍左右。
在表数据修改时,例如增加,删除,更新,都需要维护索引表,这是需要系统开销的。
不合理的索引设计非但不能利于系统,反而会使系统性能下降.
创建索引
Create [unique] [clustered] [nonclustered] index index_name on {table| view} (column [asc|desc][,...n])
[with index_option [,...n]]
[on filegroup]
删除索引
drop index ‘table.index| view.index’[ ,...n]
例:在视图 stcourse 中的 studentname 列创建一个非聚集索引。
create index index_stname on stcourse(studentname)
例:删除上例中创建的索引 index_stname。
drop index stcourse.index_stname
索引的使用原则
- 不要索引数据量不大的表,对于小表来讲,表扫的成本并不高。
- 不要设置过多的索引,在没有聚集索引的表中,最大可以设置 249 个非聚集索引,过多的索引首先会带来更大的磁盘空间,而且在数据发生修改时,对索引的维护是特别消耗性 能的。
- 合理应用复合索引,有某些情况下可以考虑创建包含所有输出列的覆盖索引。
- 对经常使用范围查询的字段,可能考虑聚集索引
- 避免对不常用的列,逻辑性列,大字段列创建索引。
高级连接
使用连接的原因
表建立时各数据之间的关系不必确定,常把一个实体的所有信息存放在一个表中。当检索数据时,通过连接操作查询出存放在多个表中的不同实体的信息。
连接出现在 from 子句或者 where 子句中。语法格式:
FROM join_table join_type join_table [ON (join_condition)]
连接的分类:
- 自连接:对同一个表操作的连接又称做自连接。
- 内连接:使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行。根据所使用的比较方式不同,内连接又分为等值连接、自然连接和不等 连接三种。
- 外连接:与内连接不同的是,外连接不只列出与连接条件相匹配的行,而是列出左表(左 外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的数据行。
- 交叉连接:没有 WHERE 子句,它返回连接表中所有数据行的笛卡尔积
内连接分类:
- 等值连接:在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接表中的所有列,包括其中的重复列。
- 不等连接: 在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些运算符包括>、>=、<=、<、!>、!<和<>。
- 自然连接:在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列 表指出查询结果集合中所包括的列,并删除连接表中的重复列。(自然连接是特殊的等值连 接)
例(内连接):
SELECT SC.*, Course.* FROM INNER JOIN Course ON(SC.Cno=Cname.Cno) SELECT SNAME, DNAME, CNO, TNAME FROM STUDENT NATURAL JOIN TEACHER
例(外连接):
SELECT SC.*, Course.* FROM SC RIGHT JOIN Course ON(SC.Cno= Course.Cno)
例(交叉连接):
select SC.*,Course.* from SC CROSS JOIN Course
本博客内容到此结束,欢迎指正!