SQL基础之select

1.认识selectsql

  select的主要语法以下,这个很重要由于只有记住了总体的结构才能应对任何状况。从中能够看到select的强大主要就是创建在where、group by、having、order by这4个功能之上。数据库

select [all | distinct] select_list [into new_table]    [from  table_source] express

[where search_condition]ide

[group by byexpression]      函数

[having search_condition]性能

[order by order_expression [asc|desc] ]网站

再来看这6个关键字的执行顺序,显然首先你得找到表取得最原始最庞大的数据,所以是from。接着是where用来进行过滤,而后group by和having开始执行,这样数据的过滤已经完成因此就是select了,还有一个order by就是最后了。总结起来顺序是from、where、group by、having、select、order by。若是再加上其它功能点,完整的执行顺序为from,on,join,where,group by,having,with rollup或cube,select,distinct,order by,top。关于from要注意当为表使用别名时,一旦使用将不可以再用表名,只能使用as后的别名。where中可使用不少运算符组合过滤条件,系统过滤数据时将按照过滤条件以行为单位一条条的进行过滤。在运算符中逻辑运算符的优先级为not、and、or,并且not只能用于简单条件式,不能用于包含and和or的复杂条件式。spa

  group by为咱们带来了很是方便的分组功能,但要注意使用时select中只能是by后面的列名和汇集函数。当以by后面的列进行分组时,若是在select中包括其它的列好比columnA,那么系统将不知道显示分组后的columnA集合中的哪一条数据,这就是为何不能select其它列的缘由。另外还要注意group by后的列名必须使用完整的名字,不能出现as的别名,缘由很简单就是由于执行顺序。having和where很类似,它们均可以对结果进行过滤。它们的区别则有2点:having中能够包含汇集函数,而where是不容许有汇集函数的;having中出现的列必须是select中存在的,而where则可使用表中的任意列。日志

  在查询中,若是要对多表进行查询可以使用where或表链接来进行关联。和表链接同样,联合查询也是查询中颇有效的手段,固然它和表链接有着本质的区别,使用它有3个要注意的地方。首先union联合的2个select语句,必需要有相同数量的列。在有相同列的状况下,列还必须拥有类似的数据类型,最后select语句的顺序也要相同。它的做用则是将多个select的结果集拼接在一块儿并一块儿显示在结果集上,表链接是将表进行关联链接,而联合查询只是联合了查询出来的结果集,将这些结果集放到一块儿显示而已。使用union会发现它除了去除重复行外,还会对结果集进行一个排序,union all既不会去除重复行也不会对结果进行排序。关于union的用法读者可本身去写sql,这里我要强调的是一个使用union常见的错误,数据表sql语句以下所示。code

--建立数据库
create database testDb  on
(
name=testDb_data,
filename='D:\testDb_data.mdf',
size=4,
filegrowth=10%
)
log on
(
name=testDb_log,
filename='D:\testDb_data.log',
size=2,
filegrowth=10%
)

--建立student表
use testDb
create table student
(
studentId int primary key,
studentName nvarchar(16) not null,
studentAge int default(18),
studentSex nchar(1)
)

create table teacher
(
teacherId int primary key,
teacherName nvarchar(16) not null,
teachClass nvarchar(16)
)

--为student添加新的一列并添加主外键约束
alter table student add
teacherId int,constraint teacher_FK foreign key(teacherId) references teacher(teacherId)
select * from teacher

insert into teacher values(1,'刘老师','安卓')
insert into teacher values(2,'吴老师','网站')
insert into teacher values(3,'王老师','物联网')

select studentId,studentName  from student 
union all
select teacherId,teacherName from teacher
View Code

若是在上面sql中的union后加上order by teacherId则会出现错误,提示上说order by项必须出如今选择列表中,但是这里teacherId明明就是选择列表中的列啊。再仔细看看结果集会发现列上的名字是以第一个select中的列名为标题的,所以这里teacherId还真没有出现选择列表中。将teacerId改成studentId或studentName将会顺利执行,关于结果集读者可自行去试。

select studentId,studentName  from student 
union all
select teacherId,teacherName from teacher 
order by teacherId

select studentId,studentName  from student 
union all
select teacherId,teacherName from teacher 
order by studentId,studentName

在错误提示中还出现了intersect和except运算符,既然遇到了那确定要掌握。这3个运算符一块儿出现说明它们有着某种紧密的联系。union如前面所说是两个数据集的并集,intersect是两个结果集的交集,except则是两个结果集的差集。以上面的表为例,若是使用intersect结果集将为空,由于这两个集合根本就没有相同的数据集。使用except则返回的是第一个select返回的结果。使用union和except的结果以下所示。

select studentId,studentName  from student 
union
select teacherId,teacherName from teacher 
order by studentId,studentName

select studentId,studentName  from student 
except
select teacherId,teacherName from teacher 
order by studentId,studentName
View Code

         

2.从select into到临时表

  在实际应用中开发者常常会须要去建立一个临时的表存储数据,select into正是扮演着这样的角色。使用select into要注意建立的表名必须是惟一的,当咱们使用select into建立一个临时的表时会在当前数据库中创建一张新表。注意这张表已存在于当前数据库中,这样的话开发者还须要手动drop,若是忘记删除将会致使数据库中的表愈来愈多,并且颇有可能重名。为了改进这一缺点,SQL利用了和C#里的垃圾回收同样的思想,就是由系统来删除临时表,固然咱们也能够手动删除。咱们只须要在设置临时表名前加上#或##,一个#表示本地临时表,两个#表示全局临时表。对于本地临时表,最重要的特色是建立后只对当前此次会话状态有效,一次会话状态指的是客户端与数据库引擎的链接,这里客户端指登入者在数据库上进行操做的一端,最终执行是须要链接数据库引擎来完成的。好比select * into #table1 from student where studentId<4,执行后在系统数据库中的tempdb可看到建立的临时表。而且它的名字颇有意思,sql多是为了防止重名吧,它还为咱们建立的本地临时表又添加了后缀名。当我关掉选项卡后,这个临时表也就从tempdb中消失了,也就是说本地临时表它属于建立它的当前用户,且只在当前会话状态下可以使用。全局临时表建立后,全部用户均可见,当建立者介绍此次会话时好比我关掉选项卡,会发现全局临时表和本地临时表一块儿被删了。那是否是说全局临时表和本地临时表同样,也是当前会话状态结束就被系统删除呢?答案是否认的,这里和GC很像,若是没有其余任务引用这个全局临时表,那它就被删除。但要注意建立着会话状态存在时,其余任务可引用它建立的全局临时表,建立着会话状态存结束时,其余任务将不能再引用这个全局临时表,可是此时若是已有任务引用这个全局临时表不会删除,直至没有任务引用它。另外临时表并非只有select into能够建立,咱们也能够直接使用create table建立。

  建立临时表和非临时表相比,有哪些优势和缺点呢?首先咱们最关注的确定是性能,临时表有一个特色那就是对它的操做不会记录日志文件,而非临时表则会进行记录,所以临时表性能比非临时表更快。在临时表中,因为本地临时表只对当前用户的当前会话状态有效,那么彻底不须要对本地临时表进行加锁,因此从这一点来讲本地临时表比全局临时表更快。显然这些性能的提升同时伴随着某些功能将没法使用,有利也有弊。临时表与非临时表同样,也能够创建索引、约束,只是不能创建外键约束,对于临时表和非临时表咱们均可以使用drop和truncate来删除表。

相关文章
相关标签/搜索