您的位置:首页 > 数据库

25. SQL -- TSQL(SELECT语句的使用,子查询,连接,通配符 )(1)

2015-03-31 17:11 477 查看
SELECT句的使用select 语句:
○5 SELECT select_list○1 FROM table_source○2 [ WHERE search_condition ]○3 [ GROUP BY group_by_expression]○4 [ HAVING search_condition ]○6 [ ORDER BY order_expresion [ASC |DESC ] ]SELECT语句执行顺序:
A、FROM阶段B、WHERE阶段C、GROUPBY阶段D、HAVING阶段E、SELECT阶段F、ORDERBY阶段1)FROM阶段:FROM 阶段标识出查询的来源表,并处理表运算符如果指定了表运算符,还需 要按从左到右的顺序,对运算符进行逐个处理。表运算符有4 类,JOIN、APPLY、PIVOT、UNPIVOT。在涉及到接运算的查询中(各种join),主要有以下几个步骤:a. 求笛卡尔积。不论是什么类型的联接运算,首先都是执行交叉连接(cross join),得出最大的可能结果集。如果左表有n 行,右表有m行,则结果集有n x m 行,求笛卡儿积,生成虚拟表VT1-J1。b. ON 筛选器。这个阶段对上个步骤生成的VT1-J1 进行筛选,根据ON 子句中出现的谓词进行筛选,让谓词取值为true 的行通过了考验,插入到VT1-J2。c. 对于外联接(left,right,full outer join),还需要添加外部行。在上个步骤中,ON 条件剔除掉了所有不匹配两张表的行。但是在外联接中,通过指定外连接的类型,需要将其中的一个或者两个表标记为保留表,并返回该表中所有的行。所以这时候还需要将保留表中被ON 筛选条件剔除的行重新加入到结果集中(这些重新加进来的表,书中称为外部行),并将外部行中非保留表的列值标记为NULL,生成VT1-J3。这一个步骤,只有外联接才执行,对于内联接(inner join)只需要执行a 和b 两个步骤的。概括地讲,FROM 阶段就是进行预处理的,根据提供的运算符对语句中提到的各个表进行处理(除了join,还有apply,pivot,unpivot)2)WHERE 阶段:WHERE 阶段是根据<where_predicate>中条件对VT1 中的行进行筛选,让条件成立的行才会插入到VT2 中。此时,因为还没有对数据进行分组,所以在where 子句中不能聚合。也不能引用select 列表中创建的别名,因为SELECT 阶段还在后面。另外,对于包含JOIN 的查询,到底ON 和WHERE 子句有什么区别,应该什么时候使用ON子句,什么时候使用where 子句?只有对于外联接,ON 和where 子句才会存在这种逻辑区别,因为在外联接中,通过ON 子句的筛选之后,还要对保留表进行外部行添加,而where 子句则是在外部行添加过之后才进行筛选的。因此,ON 子句对这种外联接的情况的筛选,并不是最终的结果,在FROM 阶段的第三个步骤,还会把外部行添加回来的。而对于内联接,where子句和on 子句作用是完全一样的,在哪里筛选都是同种效果,没有其他步骤。所以在处理这种含有外联接的查询,一定要注意ON 筛选和where 筛选的区别,避免使用错了,达不到筛选的效果。另外,对于内联接,一个不错的建议是,对于两个表都存在的字段筛选,用ON 子句,对于单个表的字段筛选,用where,例如:select * from a inner join b on a.col = b.col where a.col2>1。3)GROUP BY阶段GROUP 阶段按照指定的列名列表,将VT2中的行进行分组,生成VT3。最后每个分组只有一行。4)HAVING 阶段该阶段根据HAVING 子句中出现的谓词对VT3 的分组进行筛选,并将符合条件的组插入到VT4中。HAVING 筛选器是唯一能筛选分组数据的筛选器,ON 和where 都不行。理由很简单,ON 和where 都是在分组之前进行处理的,自然不能对分组进行筛选. 所以HAVING 和WHERE 的区别,也是很显而易见了。HAVING 只能与 SELECT 语句一起使用。HAVING 通常在 GROUP BY 子句中使用。如果不使用 GROUP BY 子句,则HAVING 的行为与WHERE子句一样。5)SELECT这个阶段是投影的过程,处理SELECT 子句提到的元素,产生VT5。这个步骤一般按下列顺序进行:a. 计算SELECT 列表中的表达式,生成VT5-1。b. 若有DISTINCT,则删除VT5-1 中的重复行,生成VT5-2c. 若有TOP,则根据ORDER BY子句定义的逻辑顺序,从VT5-2 中选择签名指定数量或者百分比的行,生成VT5-36)ORDER BY阶段根据ORDER BY子句中指定的列明列表,对VT5-3 中的行,进行排序,生成游标VC6.集合和游标:SQL 的理论基础是集合,集合是无序的,它只是成员的一种逻辑集合。对于带有排序作用的ORDER BY子句的查询,可以返回一个对象,其中的行按照特定的顺序组织在一起。ANSI 把这种对象成为游标(cursor)。因为在这一步中,最后返回的是游标,所以order by 查询,是不能用来定义视图,子查询,公用表等。例如:SELECT * FROM (SELECT col1,col2 FROM tab_test ORDER BY col1)是无效的,并且将报错。当然SQL SERVER 在实际的查询过程中,有查询优化器来生成实际的工作计划。以何种顺序来访问表,使用什么方法和索引,应用哪种联接方法,都是由查询优化器来决定的。 量:
变量对于一种语言来说是必不可少的组成部分。变量的作用:§ 作为计数器计算循环执行的次数或控制循环执行的次数。§ 保存数据值以供控制流语句测试。§ 保存存储过程返回代码要返回的数据值或函数返回值。§ SQL SERVER 2008 可以在定义变量时立即赋值 Transact-SQL 语言允许使用两种变量:一种是用户自己定义的局部变量(LocalVariable),另一种是系统提供的全局变量(GlobalVariable)。1)、局部变量:局部变量使用户自己定义的变量,它的作用范围近在程序内部。通常只能在一个批处理中或存储过程中使用,用来存储从表中查询到的数据,或当作程序执行过程中暂存变量使用,局部变量使用DECLARE 语句定义,并且指定变量的数据类型,然后可以使用SET或SELECT 语句为变量初始化;局部变量必须以“@”开头,而且必须先声明后使用。形如:@S1其声明格式如下:DECLARE @变量名变量类型[,@变量名变量类型]SELECT @局部变量=变量值附值SET @局部变量=变量值附值例:在Demo_DB 数据库中TimeRecords 表中用名为@emp 的局部变量检索所有以P11034开头的emp_id 打卡信息,代码如下:declare@emp varchar(20)select@emp = 'p110343%'select* from TimeRecordswhereemp_id like @emp执行结果:Id clock_id emp_id join_id depart_id card_id2385 105 P1103432 12443 01101003 28520362222539 105 P1103432 12443 01101003 28520362224573 105 P1103432 12443 01101003 28520362225557 102 P1103436 12447 01100502 2619730638注意:如果声明字符型的局部变量,一定要在变量类型中指明其最大长度,否则系统认为其长度为1。Select 与set 比较:l select 功能强大一点,可以一次对多个变量同时赋值;l 当源操作数不为空时,目的操作数都等于源操作数(二者此时是一样的)l 当源操作数为空(NULL)时,用set 时,目的操作数为空,用select 时,目的操作数不改变。declare@s1 varchar(10),@s2varchar(10) ,@s3 varchar(10)set @s1=10set @s2=10set @s3=10declare@s1 varchar(10),@s2varchar(10) ,@s3 varchar(10)select@s1='10', @s2= '10', @s3= '10'2)、全局变量:全局变量是SQL Server 系统内部使用的变量,起作用范围并不局限于某一程序,而是任何程序均可随时调用。全局变量通常存储一些SQL Server 的配置设置值和效能统计数据。用户可在程序中用全局变量来测试系统的设定值或者Transact_SQL命令执行后的状态值。引用全局变量时,全局变量的名字前面要有两个标记符“@@”。不能定义与全局变量同名的局部变量.形如:@@s1。全局变量及其功能:全局变量 功 能@@CONNECTIONS自SQL Server 最近一次启动以来登录或试图登录的次数@@CPU_BUSY自SQL Server 最近一次启动以来CPU Server 的工作时间@@CURRSOR_ROWS返回在本次连接最新打开的游标中的行数@@DATEFIRST返回SETDATEFIRST 参数的当前值@@DBTS数据库的惟一时间标记值@@ERROR系统生成的最后一个错误,若为0 则成功@@FETCH_STATUS最近一条FETCH 语句的标志@@IDENTITY保存最近一次的插入身份值@@IDLE自CPU 服务器最近一次启动以来的累计空闲时间@@IO_BUSY服务器输入输出操作的累计时间@@LANGID当前使用的语言的ID@@LANGUAGE当前使用语言的名称@@LOCK_TIMEOUT返回当前锁的超时设置@@MAX_CONNECTIONS同时与SQL Server 相连的最大连接数量@@MAX_PRECISION十进制与数据类型的精度级别@@NESTLEVEL当前调用存储过程的嵌套级,范围为0~16@@OPTIONS返回当前SET 选项的信息@@PACK_RECEIVED所读的输入包数量@@PACKET_SENT所写的输出包数量@@PACKET_ERRORS读与写数据包的错误数@@RPOCID当前存储过程的ID@@REMSERVER返回远程数据库的名称@@ROWCOUNT最近一次查询涉及的行数@@SERVERNAME本地服务器名称@@SERVICENAME当前运行的服务器名称@@SPID当前进程的ID@@TEXTSIZE当前最大的文本或图像数据大小@@TIMETICKS每一个独立的计算机报时信号的间隔(ms)数,报时信号为31.25ms 或1/32s@@TOTAL_ERRORS读写过程中的错误数量@@TOTAL_READ读磁盘次数(不是高速缓存)@@TOTAL_WRITE写磁盘次数@@TRANCOUNT当前用户的活动事务处理总数@@VERSION当前SQL Server 的版本号
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  通配符 笛卡儿